Python爬虫实战:Requests与BeautifulSoup数据抓取与解析指南

在数据驱动的时代,网络爬虫已成为获取公开信息的重要工具。本文将通过完整源码示例,详细讲解如何使用Python的requests库实现HTTP请求,结合BeautifulSoup进行HTML解析,帮助开发者掌握基础爬虫开发技能。

一、环境准备与基础概念

1.1 核心库安装

bash

1pip install requests beautifulsoup4 lxml
2
  • requests:轻量级HTTP请求库,支持GET/POST等协议
  • BeautifulSoup:HTML/XML解析库,提供DOM树遍历接口
  • lxml:高性能解析器(比内置html.parser快5-10倍)

1.2 爬虫工作原理

  1. 请求阶段:模拟浏览器发送HTTP请求
  2. 解析阶段:将HTML转换为可操作的数据结构
  3. 提取阶段:定位目标数据并提取
  4. 存储阶段:将结果保存到文件或数据库

二、基础爬虫实现

2.1 豆瓣电影Top250爬取示例

python

1import requests
2from bs4 import BeautifulSoup
3import csv
4
5# 请求头配置
6headers = {
7    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
8}
9
10# 发送请求
11def fetch_page(url):
12    try:
13        response = requests.get(url, headers=headers, timeout=10)
14        response.raise_for_status()
15        response.encoding = response.apparent_encoding
16        return response.text
17    except Exception as e:
18        print(f"请求失败: {e}")
19        return None
20
21# 解析页面
22def parse_html(html):
23    soup = BeautifulSoup(html, 'lxml')
24    items = soup.find_all('div', class_='item')
25    
26    results = []
27    for item in items:
28        rank = item.find('em').text
29        title = item.find('span', class_='title').text
30        rating = item.find('span', class_='rating_num').text
31        num_reviews = item.find('div', class_='star').find_all('span')[-1].text.strip('人评价')
32        
33        quote_tag = item.find('span', class_='inq')
34        quote = quote_tag.text if quote_tag else '无简介'
35        
36        results.append({
37            '排名': rank,
38            '电影名称': title,
39            '评分': rating,
40            '评价人数': num_reviews,
41            '简介': quote
42        })
43    return results
44
45# 主程序
46if __name__ == '__main__':
47    base_url = 'https://movie.douban.com/top250?start={}'
48    all_data = []
49    
50    for page in range(0, 250, 25):
51        url = base_url.format(page)
52        html = fetch_page(url)
53        if html:
54            page_data = parse_html(html)
55            all_data.extend(page_data)
56            print(f"已抓取第{page//25 + 1}页数据")
57    
58    # 保存CSV
59    with open('douban_top250.csv', 'w', newline='', encoding='utf-8-sig') as f:
60        writer = csv.DictWriter(f, fieldnames=all_data[0].keys())
61        writer.writeheader()
62        writer.writerows(all_data)
63    print("数据保存完成")
64

2.2 代码解析要点

  1. 请求头设置:通过User-Agent模拟浏览器访问
  2. 异常处理:使用try-except捕获网络请求异常
  3. 编码处理response.apparent_encoding自动检测编码
  4. DOM解析
    • find_all():批量查找元素
    • class_参数:注意末尾下划线(避免与Python关键字冲突)
    • 链式调用:item.find().find()逐级定位
  5. 数据存储:使用csv.DictWriter实现字典写入

三、进阶技巧

3.1 动态参数处理

当目标URL包含动态参数时(如分页的start=25),可通过字符串格式化实现:

python

1# 分页参数处理示例
2for page in range(0, 250, 25):
3    url = f'https://movie.douban.com/top250?start={page}'
4

3.2 复杂选择器应用

python

1# 使用CSS选择器定位元素
2soup.select('div.item > div.pic > a > img')  # 层级选择
3soup.select('a[href^="https"]')             # 属性选择(href以https开头)
4soup.select('span.inq:contains("人生")')    # 文本内容选择(需配合其他库实现)
5

3.3 反爬策略应对

  1. IP限制
    • 使用代理IP池(如proxies={'http':'120.194.55.139:6969'}
    • 控制请求频率(time.sleep(2)
  2. 验证码识别
    • 结合pytesseract进行图形验证码识别
    • 使用selenium模拟人工操作
  3. Cookie管理
python

1# 维持会话示例
2session = requests.Session()
3session.get('https://www.douban.com')  # 先访问登录页
4response = session.get('https://movie.douban.com/top250')  # 后续请求携带Cookie
5

四、最佳实践

  1. 遵守robots协议
    • 访问https://target.com/robots.txt查看爬取规则
    • 避免高频请求(建议间隔3-5秒)
  2. 数据清洗
python

1# 去除空白字符
2title = item.find('span', class_='title').text.strip()
3
4# 处理异常值
5num_reviews = item.find('div', class_='star').find_all('span')[-1].text
6num_reviews = num_reviews.replace('人评价', '').strip() if '人评价' in num_reviews else '0'
7
  1. 日志记录
python

1import logging
2
3logging.basicConfig(
4    filename='spider.log',
5    level=logging.INFO,
6    format='%(asctime)s - %(levelname)s - %(message)s'
7)
8
9logging.info(f"成功抓取第{page}页数据")
10

五、常见问题解决方案

5.1 编码乱码问题

python

1# 强制指定编码(当自动检测失效时)
2response.encoding = 'utf-8'  # 或 'gbk'/'gb2312'
3

5.2 元素定位失败

  1. 使用浏览器开发者工具(F12)检查元素实际结构
  2. 尝试多种选择器组合:
python

1# 备用定位方案
2title = item.find('span', attrs={'class': 'title'}).text
3title = item.select_one('span.title').text
4

5.3 网络请求失败

  1. 检查目标网站是否启用反爬机制
  2. 增加重试机制:
python

1from requests.adapters import HTTPAdapter
2from urllib3.util.retry import Retry
3
4session = requests.Session()
5retries = Retry(total=3, backoff_factor=1)
6session.mount('http://', HTTPAdapter(max_retries=retries))
7session.mount('https://', HTTPAdapter(max_retries=retries))
8
9response = session.get(url)
10

六、总结

本文通过完整案例展示了Python爬虫开发的核心流程:

  1. 使用requests实现稳定网络请求
  2. 通过BeautifulSoup进行高效DOM解析
  3. 结合CSV模块实现结构化数据存储
  4. 介绍反爬策略应对方案

建议开发者在实际项目中:

  • 优先使用官方API获取数据
  • 严格控制爬取频率
  • 做好异常处理和日志记录
  • 定期更新User-Agent池

完整源码已通过Python 3.8+环境测试,可根据实际需求调整选择器逻辑和存储方式。掌握这些基础技能后,可进一步学习Scrapy框架或Selenium自动化测试工具,应对更复杂的爬取场景。

会员自媒体 Python Python爬虫实战:Requests与BeautifulSoup数据抓取与解析指南 https://yuelu1.cn/26283.html

相关文章

猜你喜欢