2022-03-19 02:03:36
代码存在以下问题,导致报错或无法正确提取数据:
1. 反爬机制未完全绕过尝试添加更多请求头字段(如Referer、Cookie等),或使用Session对象维持会话。
使用代理IP池避免被封禁。
示例代码(补充Referer):headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', 'Referer': '
正则表达式<li.>.*?和<li.>.*?<img .../>存在语法问题:
<li.>中的.未转义,会匹配任意字符(包括>),导致匹配范围失控。
未明确匹配<li>标签的闭合结构(如</li>),可能截取不完整内容。
目标字段(title、score、image)未在正则中明确定位,直接通过item[0]等索引会报错(findall返回的是字符串列表,非元组)。
修正正则表达式,明确匹配<li>标签及其内容:pattern = re.compile(r'<li.*?class="list-item".*?>.*?<img src="(.*?)".*?title="(.*?)".*?data-score="(.*?)".*?</li>', re.S)items = re.findall(pattern, html)for item in items: a = {'title': item[1], 'score': item[2], 'image': item[0]} print(a)
说明:
假设目标数据在<li class="list-item">标签内,且包含<img>的src、标题title和数据分数data-score。
实际需根据豆瓣页面真实HTML结构调整正则。
原代码中a={'title': item[0], 'score': item[1], 'image': item[2]}假设item是包含3个元素的元组,但re.findall返回的是字符串列表(每个字符串匹配整个正则模式)。
确保正则表达式中使用分组(())捕获目标字段,findall会返回分组元组的列表。
示例修正:# 正则中分组捕获image、title、scorepattern = re.compile(r'<li.*?src="(.*?)".*?title="(.*?)".*?data-score="(.*?)".*?</li>', re.S)items = re.findall(pattern, html) # items是元组列表,如[('img1.jpg', '电影A', '9.0'), ...]for item in items: a = {'title': item[1], 'score': item[2], 'image': item[0]} print(a)
未捕获requests.get()可能抛出的异常(如网络错误、超时)。
未检查响应状态码(如response.status_code是否为200)。
添加异常处理和状态码检查:try: response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() # 非200状态码抛出异常 html = response.textexcept RequestException as e: print(f"请求失败: {e}") exit()
正则表达式解析HTML易出错,尤其对复杂页面。
使用lxml或parsel库通过XPath/CSS选择器提取数据,更稳定。
示例代码:from parsel import Selectorselector = Selector(text=html)items = selector.css('li.list-item').getall() # 假设目标在li.list-item中for item in items: title = selector.css(item).xpath('.//@title').get() score = selector.css(item).xpath('.//@data-score').get() image = selector.css(item).xpath('.//img/@src').get() print({'title': title, 'score': score, 'image': image})
关键改进点: