Python使用requests做网页爬虫如何从JSONP响应中提取链接
方案1:规范解析(推荐)
你拿到的是JSONP格式的响应,这种格式会用请求参数里的callback值包裹真实JSON数据,我们可以先剥离外层包装、解析出HTML内容,再用HTML解析库提取链接,准确率最高不会出现误匹配。
依赖安装
pip install requests beautifulsoup4
完整实现代码
import requests import json from bs4 import BeautifulSoup headers = { 'authority': 'www.xxxxxx.net', 'sec-ch-ua': '"Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"', 'accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01', 'x-requested-with': 'XMLHttpRequest', 'sec-ch-ua-mobile': '?0', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://www.xxxxxx.net/', 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 'cookie': 'bnState={"impressions":1,"delayStarted":0}; pnState="impressions":2,"delayStarted":1635254046187}', } params = ( ('alt', 'json-in-script'), ('max-results', '12'), ('start-index', '13'), ('callback', 'jQuery22404432064732296963_1635254045161'), ('_', '1635254045166'), ) response = requests.get('https://www.xxxxxx.net/feeds/posts/default', params=params) # 剥离JSONP外层的callback包装 jsonp_str = response.text start = jsonp_str.find('(') + 1 end = jsonp_str.rfind(')') json_str = jsonp_str[start:end] # 解析JSON数据 data = json.loads(json_str) # 提取HTML内容,以下路径可根据实际返回的JSON结构调整 html_content = data['feed']['entry'][0]['content']['$t'] # 解析HTML提取链接 soup = BeautifulSoup(html_content, 'html.parser') all_links = set() # 提取所有a标签的href链接 for a in soup.find_all('a', href=True): all_links.add(a['href']) # 提取所有img标签的src链接,如果不需要可以删除这段 for img in soup.find_all('img', src=True): all_links.add(img['src']) # 输出所有去重后的链接 for link in all_links: print(link)
方案2:正则快速匹配(适合临时使用)
如果不需要严格区分链接类型,只是要快速提取所有HTTP/HTTPS开头的链接,可以直接用正则匹配响应内容,无需解析JSON和HTML:
import re import requests # 前面的请求代码保持不变 response = requests.get('https://www.xxxxxx.net/feeds/posts/default', params=params) # 正则匹配所有合法HTTP链接 pattern = re.compile(r'https?://[^\s"\'<>]+') all_links = set(pattern.findall(response.text)) # 输出结果 for link in all_links: print(link)
注意事项
- 使用方案1时可以先打印解析后的
data变量,确认HTML内容在JSON中的实际存储路径,调整代码中的html_content取值逻辑即可。 - 如果只需要提取页面跳转链接,删除方案1中提取img标签src的代码段即可。
内容的提问来源于stack exchange,提问作者ravi prakash
相关产品推荐
相关产品推荐

