使用re.findall结合requests无法匹配requests.text返回的HTML内容
使用re.findall结合requests无法匹配requests.text返回的HTML内容
看起来你遇到了一个爬虫圈很常见的困境——直接复制浏览器里的HTML能精准匹配到目标内容,但用requests.get获取的原始HTML却完全匹配不到。咱们一步步拆解原因,再给出对应的解决办法。
核心差异分析
先帮你理清两种场景的本质区别:
- 转义字符/编码差异:你从浏览器复制的HTML,浏览器已经自动处理了部分转义(比如把
\\"显示为"),但requests.get返回的response.text是服务器直接返回的原始内容,可能包含额外的转义标记(比如双引号被转义为\"),导致你的正则表达式无法匹配。 - 动态内容渲染(最可能的原因):像Asura Comic这类漫画站点,通常会用JavaScript动态加载图片资源链接。
requests.get只能拿到服务器返回的初始静态HTML,而你从浏览器复制的是浏览器执行JS后渲染完成的完整HTML——你要找的{"order":...,"url":...}这段数据,其实是JS运行后才注入到页面的,根本不在requests获取的原始HTML里。
快速验证问题根源
你可以做个简单对比:
- 打开用
requests保存的raw_html.html,搜索关键词"order":或者.webp。 - 如果搜不到目标内容,100%是动态加载的问题;如果能搜到,那就是转义/编码的锅。
针对性解决方案
方案1:调整正则适配转义字符(应对转义差异)
如果是转义问题,修改正则表达式,让它能匹配带转义的双引号:
# 匹配可能被转义的双引号,兼容原始内容的转义格式 pattern = r'{\\?"order\\?":\d+,\\?"url\\?":"(https:[^"\\]+\\?.webp)"\\?}'
或者用更稳妥的方式解析JSON片段:
import json from bs4 import BeautifulSoup # 先用BeautifulSoup定位包含目标数据的脚本标签 soup = BeautifulSoup(html_content, "html.parser") for script in soup.find_all("script"): if "order" in script.text and "url" in script.text: # 截取JSON片段(需根据实际内容调整截取逻辑) json_str = script.text.split("window.__IMAGE_DATA__ = ")[1].split(";")[0] image_list = json.loads(json_str) # 直接提取图片链接 for item in image_list: print(item["url"])
方案2:用Selenium获取渲染后的完整HTML(应对动态内容)
如果是JS动态加载的问题,requests就无能为力了,需要用Selenium模拟浏览器加载页面,等待JS执行完成后再获取HTML:
import re from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By url = "https://asuracomic.net/series/bloodhounds-regression-instinct-2d0edc16/chapter/59" # 初始化Chrome浏览器(需提前安装ChromeDriver并配置到环境变量) driver = webdriver.Chrome() driver.get(url) # 等待页面加载完成(这里以等待图片元素出现为判断条件,超时10秒) try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, "img")) ) finally: # 获取渲染后的完整HTML html_content = driver.page_source driver.quit() # 用你原来的正则匹配即可 pattern = r'{"order":\d+,"url":"(https:[^"]+\.webp)"}' matches = re.findall(pattern, html_content) for match in matches: print(match)
方案3:直接抓取API接口(最优解)
比起解析HTML,直接调用站点的图片接口效率更高、稳定性更好。你可以按以下步骤找到目标API:
- 打开浏览器开发者工具(F12),切换到「Network」标签页,过滤「XHR/Fetch」类型的请求。
- 刷新目标章节页面,查找包含图片列表的API(比如路径包含
chapter、images的请求),查看响应会发现是JSON格式的数据,直接包含order和url字段。 - 直接用
requests请求这个API即可:
import requests # 替换为你找到的真实API接口地址 api_url = "https://asuracomic.net/api/chapters/59/images" headers = { "Referer": "https://asuracomic.net/series/bloodhounds-regression-instinct-2d0edc16/chapter/59", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } response = requests.get(api_url, headers=headers) image_data = response.json() for item in image_data: print(item["url"])
总结
优先推荐方案3(抓取API接口),它是效率最高、最稳定的方式;如果找不到API,再用方案2(Selenium)处理动态内容;只有确认是转义问题时,再用方案1调整正则。
备注:内容来源于stack exchange,提问作者Addoodi
相关产品推荐
相关产品推荐

