使用Python bs4库提取<head>中script标签内容返回None如何解决
问题排查与解决方法
- 第一步:先解决反爬拦截问题
大部分网站会识别requests的默认请求标识,直接返回空页面或者拦截页,返回的源码里根本没有你要的目标script标签,自然会取到None。你需要在请求时添加User-Agent伪装成浏览器发起的请求:import requests from bs4 import BeautifulSoup headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } link='https://reelgood.com/movie/dollars-1971' source = requests.get(link, headers=headers).text # 可以先打印源码长度判断是否被拦截,正常页面长度一般在几万以上 print(len(source)) - 第二步:不要硬编码script标签的顺序位置
nth-of-type(14)是非常不稳定的选择器,页面稍有更新、不同页面的script数量变化都会导致定位失效。你要的目标script有固定特征包含_rg.update字符串,直接按内容特征定位更可靠:soup = BeautifulSoup(source, "html.parser") # 筛选包含特征字符串的script标签 content = soup.find('script', string=lambda s: s and '_rg.update' in s) print(content) - 可选优化:替换解析器
如果还是获取不到,可以把html.parser换成容错性更高的lxml解析器,需要先安装依赖:pip install lxml,再修改初始化代码:soup = BeautifulSoup(source, "lxml") - 后续数据提取
拿到目标script内容后,可以用正则提取JSON结构再解析获取字段:import re import json if content: js_content = content.get_text() # 提取_rg.update括号里的JSON字符串 json_str = re.search(r'_rg.update\((.*?)\)\s*;?', js_content, re.S).group(1) data = json.loads(json_str) # 后续按需取字段即可,比如电影标题在data['bootstrap']['entities']['entries']的对应节点下
内容的提问来源于stack exchange,提问作者Ori Peleg
相关产品推荐
相关产品推荐

