python3爬虫笔记2

'# python3爬虫笔记2

一、背景与问题

在前一篇文章中,我们介绍了基础的爬虫实现方式,但实际开发中会遇到更复杂的场景:网页内容可能包含JavaScript动态加载、反爬虫机制、复杂的数据结构、需要处理认证授权等问题。本文将深入探讨爬虫技术的核心原理,结合真实项目场景,分析不同实现方式的优劣。

二、基本原理

1. 网络请求的底层机制

HTTP协议是爬虫交互的核心,理解其工作原理是实现反爬策略的基础。网络请求包含以下几个关键要素:

  • 请求方法(GET/POST)
  • 请求头(Headers)
  • 请求体(Body)
  • 状态码(Status Code)
  • 响应内容(Response Body)
import requests

response = requests.get('https://example.com', headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
})
print(response.status_code)
print(response.text)
代码解释:通过requests库发送GET请求,设置User-Agent头模拟浏览器访问。注意status_code表示服务器响应状态码,text属性包含原始响应内容。

2. 动态内容处理机制

现代网页大量使用JavaScript动态渲染内容,传统requests库无法直接获取动态生成的内容。此时需要引入以下技术:

  • Selenium:通过浏览器自动化控制获取DOM
  • Playwright:更现代的浏览器自动化工具
  • Pyppeteer:基于Chromium的异步爬虫库
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://example.com')
print(driver.page_source)
driver.quit()
代码解释:使用Selenium启动Chrome浏览器实例,获取完整页面源码。注意需要安装chromedriver并配置环境变量。

三、环境准备

pip install requests beautifulsoup4 selenium playwright

环境配置说明:

  1. Python 3.8+ 版本
  2. Chrome浏览器(建议使用最新稳定版)
  3. chromedriver 与 Chrome 版本对应
  4. Playwright 需要安装浏览器二进制文件(通过playwright install自动安装)

四、核心实现

1. 请求头构造策略

复杂的反爬机制常通过请求头验证,需要构造完整的请求头信息:

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Referer': 'https://example.com/',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1'
}
代码解释:构建完整的请求头信息,包含常见的浏览器特征字段。注意Referer字段可以防止某些网站的防盗链机制。

2. 网页解析技术

BeautifulSoup和lxml是常用的解析库,支持多种解析方式:

from bs4 import BeautifulSoup

soup = BeautifulSoup(response.text, 'html.parser')
print(soup.find_all('a'))
代码解释:使用html.parser解析器获取所有超链接。注意对于复杂结构需要结合CSS选择器进行定位。

3. 动态内容处理

使用Playwright处理JavaScript动态加载内容:

from playwright.sync import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto('https://example.com')
    page.wait_for_selector('div.content')
    print(page.text_content('div.content'))
    browser.close()
代码解释:通过Playwright的同步API获取动态加载的内容,wait_for_selector确保DOM加载完成。

五、完整案例

案例:爬取知乎文章内容

需求:获取指定话题下所有文章的标题和链接,保存为JSON文件。

import json
import requests
from bs4 import BeautifulSoup

def get_zhihu_topics(topic_id):
    url = f'https://www.zhihu.com/hotsearch/page/{topic_id}'
    headers = {
        'User-Agent': 'Mozilla/5.0',
        'Referer': 'https://www.zhihu.com/'
    }
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    articles = []
    for item in soup.select('.List-item'):
        title = item.select_one('.List-item-title').text.strip()
        link = item.select_one('.List-item-title').get('href')
        articles.append({
            'title': title,
            'link': f'https://www.zhihu.com{link}'
        })
    return articles

def save_to_json(data, filename):
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=4)

if __name__ == '__main__':
    data = get_zhihu_topics(1)
    save_to_json(data, 'zhihu_topics.json')
代码解释:该案例包含完整的爬虫流程,包括请求发送、响应解析和结果保存。注意知乎可能有反爬机制,需要处理验证码等特殊情况。

六、源码解析

1. requests库的底层机制

requests库基于urllib3实现,关键流程如下:

  1. 构造请求对象(Request)
  2. 生成会话(Session)
  3. 发送请求(send)
  4. 处理响应(Response)
import requests

response = requests.get('https://example.com')
print(response.request.headers)  # 请求头
print(response.headers)          # 响应头
print(response.text)            # 响应内容

2. Playwright的异步架构

Playwright支持同步和异步两种模式,其核心架构包含:

  • 浏览器管理(Browser)
  • 页面管理(Page)
  • 选择器系统(Selector)
  • 网络请求拦截(Route)
from playwright.async_api import async_playwright

async def run():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        await page.goto('https://example.com')
        await page.wait_for_selector('div.content')
        print(await page.text_content('div.content'))
        await browser.close()

run()

七、进阶使用

1. 处理反爬机制

常见反爬策略及应对方案:

反爬策略应对方案
User-Agent识别随机User-Agent池
IP封禁使用代理池
验证码模拟人工操作
请求频率限制增加随机延迟
import random
import time

def random_delay():
    time.sleep(random.uniform(1, 3))  # 随机等待1-3秒

2. 处理动态加载内容

对于复杂网页,可以使用Playwright的page.wait_for_function方法:

await page.wait_for_function('document.querySelectorAll("div.content").length > 0')

八、性能与工程实践

1. 性能优化策略

优化策略说明
并发请求使用concurrent.futures或asyncio
缓存机制使用Redis缓存响应内容
异步处理使用aiohttp和async/await
from aiohttp import ClientSession
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with ClientSession() as session:
        tasks = [fetch(session, 'https://example.com') for _ in range(10)]
        results = await asyncio.gather(*tasks)

2. 异常处理机制

try:
    response = requests.get(url, timeout=5)
    response.raise_for_status()
except requests.exceptions.HTTPError as e:
    print(f"HTTP error: {e}")
except requests.exceptions.Timeout:
    print("Request timeout")

九、常见问题与踩坑

1. 常见错误示例

# 错误示例:未处理异常
requests.get('https://example.com')
错误分析:未处理异常会导致程序崩溃,应添加异常捕获机制。

2. 反爬策略应对

问题解决方案
IP被封使用代理池轮换IP
验证码使用OCR识别或模拟人工操作
动态内容使用Playwright等浏览器自动化工具

3. 安全风险分析

  1. 数据泄露:爬取敏感信息需遵守数据保护法规
  2. 法律风险:违反网站robots.txt规则可能导致法律纠纷
  3. 服务器攻击:高频请求可能被服务器封禁

十、最佳实践

1. 推荐方案

  1. 简单静态页面:requests + BeautifulSoup
  2. 动态内容页面:Playwright或Selenium
  3. 高并发场景:aiohttp + asyncio

2. 推荐代码结构

project/
├── config/
│   └── settings.py
├── core/
│   ├── crawler.py
│   └── parser.py
├── utils/
│   ├── proxy_pool.py
│   └── retry.py
├── logs/
│   └── crawler.log
├── data/
│   └── output.json
└── requirements.txt

十一、总结

本文深入探讨了Python爬虫技术的核心原理,分析了不同场景下的实现方案。从基础的HTTP请求到复杂的动态内容处理,从反爬策略到性能优化,覆盖了实际开发中可能遇到的各类问题。在实际项目中,需要根据具体需求选择合适的工具:对于简单静态页面使用requests库即可,对于动态内容需要引入浏览器自动化工具,对于高并发场景则需要异步处理。同时要注意法律风险和安全问题,确保爬虫行为符合法律法规。

最后修改于:2026年09月24日 16:21

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日