入门爬虫,不讲道理,只摆问题

入门爬虫,不讲道理,只摆问题
最新回答
Cc°果冻

2022-03-19 02:03:36

代码存在以下问题,导致报错或无法正确提取数据

1. 反爬机制未完全绕过
  • 问题描述:虽然添加了User-Agent,但豆瓣可能还有其他反爬措施(如Cookies验证、IP限制等),仅靠User-Agent可能不足以绕过。
  • 解决方案

    尝试添加更多请求头字段(如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': '

    https://movie.douban.com/'
    }

2. 正则表达式错误
  • 问题描述

    正则表达式<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结构调整正则。

3. 数据提取逻辑错误
  • 问题描述

    原代码中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)

4. 未处理异常情况
  • 问题描述

    未捕获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()

5. 推荐替代方案:使用XPath或CSS选择器
  • 问题描述

    正则表达式解析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})

完整修正代码示例import reimport requestsfrom requests import RequestExceptionurl = "
https://movie.douban.com/cinema/nowplaying/shanghai/"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': '
https://movie.douban.com/'
}try: response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() html = response.textexcept RequestException as e: print(f"请求失败: {e}") exit()# 修正后的正则(需根据实际HTML调整)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)

关键改进点

  • 完善反爬头信息。
  • 修正正则表达式,明确分组捕获。
  • 添加异常处理和状态码检查。
  • 建议后续学习XPath/CSS选择器替代正则。