一溪风江月

技术博主 | 全栈开发者 | AI爱好者

Python爬虫从入门到精通

Python爬虫是获取互联网数据的重要技术,广泛应用于数据采集、数据分析、自动化测试等领域。本文将详细介绍Python爬虫的常用库、使用方法、实战案例以及常见问题解答,帮助你从入门到精通Python爬虫技术。

一、爬虫基础概念

1. 什么是网络爬虫?

答:网络爬虫(Web Crawler)是一种自动化程序,它可以模拟浏览器访问网页,获取网页内容,并从中提取有用的数据。爬虫广泛应用于搜索引擎、数据采集、内容聚合等领域。

2. 爬虫的工作原理

  1. 发送请求:向目标网站发送HTTP请求
  2. 获取响应:接收服务器返回的HTML页面
  3. 解析页面:从HTML中提取目标数据
  4. 存储数据:将数据保存到数据库或文件
  5. 递归爬取:发现新的链接并继续爬取

3. 爬虫的分类

  • 通用爬虫:如搜索引擎爬虫,爬取整个互联网
  • 聚焦爬虫:只爬取特定领域的网页
  • 增量爬虫:只爬取更新的内容
  • 分布式爬虫:多台机器协同爬取

二、常用爬虫库介绍

1. requests库

requests是Python最常用的HTTP请求库,简单易用,功能强大。

安装

pip install requests

基本用法

import requests

# GET请求
response = requests.get('https://www.example.com')
print(response.status_code)
print(response.text)

# POST请求
data = {'username': 'test', 'password': '123456'}
response = requests.post('https://www.example.com/login', data=data)

# 设置请求头
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0'
}
response = requests.get('https://www.example.com', headers=headers)

# 设置超时
response = requests.get('https://www.example.com', timeout=10)

# 会话保持
session = requests.Session()
session.get('https://www.example.com/login')
response = session.get('https://www.example.com/profile')

常见方法

方法 说明
requests.get() 发送GET请求
requests.post() 发送POST请求
requests.put() 发送PUT请求
requests.delete() 发送DELETE请求
response.text 获取响应文本
response.json() 获取JSON响应
response.content 获取二进制响应
response.headers 获取响应头

2. BeautifulSoup库

BeautifulSoup是一个HTML/XML解析库,可以方便地从网页中提取数据。

安装

pip install beautifulsoup4

基本用法

from bs4 import BeautifulSoup

html = '''
<html>
    <head><title>测试页面</title></head>
    <body>
        <div class="content">
            <h1>Hello World</h1>
            <p class="desc">这是一段描述</p>
            <a href="https://example.com">链接</a>
        </div>
    </body>
</html>
'''

soup = BeautifulSoup(html, 'html.parser')

# 通过标签名查找
title = soup.title
print(title.string)

# 通过类名查找
content = soup.find('div', class_='content')
print(content)

# 通过id查找
element = soup.find(id='main')

# 查找多个元素
paragraphs = soup.find_all('p')

# 获取文本
text = content.get_text()

# 获取属性
link = soup.find('a')
print(link['href'])

选择器方法

方法 说明
find() 查找第一个匹配的元素
find_all() 查找所有匹配的元素
select() 使用CSS选择器查找
select_one() 使用CSS选择器查找第一个
get_text() 获取元素文本
['attr'] 获取元素属性

3. lxml库

lxml是一个高性能的HTML/XML解析库,支持XPath选择器。

安装

pip install lxml

基本用法

from lxml import etree

html = '''
<html>
    <body>
        <div id="container">
            <ul>
                <li class="item">Item 1</li>
                <li class="item">Item 2</li>
                <li class="item">Item 3</li>
            </ul>
        </div>
    </body>
</html>
'''

tree = etree.HTML(html)

# XPath选择器
items = tree.xpath('//li[@class="item"]/text()')
print(items)

# 获取属性
links = tree.xpath('//a/@href')

# 层级选择
container = tree.xpath('//div[@id="container"]')[0]
items = container.xpath('.//li/text()')

4. Scrapy框架

Scrapy是一个强大的爬虫框架,提供了完整的爬虫解决方案。

安装

pip install scrapy

创建爬虫项目

# 创建项目
scrapy startproject myspider

# 创建爬虫
cd myspider
scrapy genspider example example.com

爬虫代码示例

import scrapy

class ExampleSpider(scrapy.Spider):
    name = 'example'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com']

    def parse(self, response):
        # 提取数据
        title = response.css('h1::text').get()
        yield {'title': title}

        # 提取链接
        links = response.css('a::attr(href)').getall()
        for link in links:
            yield response.follow(link, callback=self.parse)

运行爬虫

scrapy crawl example
scrapy crawl example -o output.json

5. Selenium库

Selenium是一个自动化测试工具,可以模拟浏览器行为,适用于动态网页。

安装

pip install selenium

基本用法

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

# 启动浏览器
driver = webdriver.Chrome()

# 访问网页
driver.get('https://www.google.com')

# 查找元素
search_box = driver.find_element(By.NAME, 'q')

# 输入内容
search_box.send_keys('Python爬虫')

# 提交搜索
search_box.send_keys(Keys.ENTER)

# 等待加载
time.sleep(2)

# 提取数据
results = driver.find_elements(By.CSS_SELECTOR, 'h3')
for result in results:
    print(result.text)

# 关闭浏览器
driver.quit()

6. 其他常用库

库名 用途
urllib Python标准库,HTTP请求
re 正则表达式,文本匹配
json JSON数据处理
pandas 数据处理和分析
pymysql MySQL数据库操作
redis Redis缓存操作
fake-useragent 随机生成User-Agent
pyquery 类似jQuery的选择器

三、爬虫实战案例

案例1:爬取新闻网站

import requests
from bs4 import BeautifulSoup

def crawl_news(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0'
    }
    
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    news_list = []
    articles = soup.find_all('article', class_='news-item')
    
    for article in articles:
        title = article.find('h2').get_text()
        link = article.find('a')['href']
        summary = article.find('p').get_text()
        
        news_list.append({
            'title': title,
            'link': link,
            'summary': summary
        })
    
    return news_list

if __name__ == '__main__':
    news = crawl_news('https://news.example.com')
    for item in news:
        print(f"标题: {item['title']}")
        print(f"链接: {item['link']}")
        print(f"摘要: {item['summary']}")
        print('---')

案例2:爬取图片

import requests
from bs4 import BeautifulSoup
import os

def download_images(url, save_dir='images'):
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0'
    }
    
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    images = soup.find_all('img', class_='gallery-img')
    
    for i, img in enumerate(images):
        img_url = img['src']
        if not img_url.startswith('http'):
            img_url = 'https://example.com' + img_url
        
        try:
            img_response = requests.get(img_url, headers=headers)
            with open(f'{save_dir}/image_{i+1}.jpg', 'wb') as f:
                f.write(img_response.content)
            print(f'下载成功: image_{i+1}.jpg')
        except Exception as e:
            print(f'下载失败: {img_url}, 错误: {e}')

if __name__ == '__main__':
    download_images('https://example.com/gallery')

案例3:爬取API数据

import requests
import json

def crawl_api(base_url, pages=5):
    all_data = []
    
    for page in range(1, pages+1):
        url = f'{base_url}?page={page}&limit=20'
        
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0',
            'Authorization': 'Bearer your_token'
        }
        
        response = requests.get(url, headers=headers)
        
        if response.status_code == 200:
            data = response.json()
            all_data.extend(data['items'])
            print(f'第 {page} 页爬取完成')
        else:
            print(f'第 {page} 页爬取失败')
    
    return all_data

if __name__ == '__main__':
    data = crawl_api('https://api.example.com/data')
    with open('data.json', 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    print(f'共爬取 {len(data)} 条数据')

四、反爬虫策略与应对

1. 常见反爬虫手段

  • User-Agent检测:检查请求头中的User-Agent
  • IP封禁:封禁频繁访问的IP地址
  • Cookie验证:需要登录或携带特定Cookie
  • 验证码:图形验证码、滑块验证等
  • 频率限制:限制单位时间内的请求次数
  • 动态渲染:使用JavaScript动态生成内容
  • Referer检查:检查请求来源

2. 反爬虫应对策略

策略1:设置请求头

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'Referer': 'https://www.example.com',
    'Connection': 'keep-alive'
}

策略2:使用代理IP

proxies = {
    'http': 'http://proxy.example.com:8888',
    'https': 'https://proxy.example.com:8888'
}

response = requests.get('https://www.example.com', proxies=proxies)

策略3:设置请求间隔

import time
import random

for url in urls:
    response = requests.get(url, headers=headers)
    time.sleep(random.uniform(1, 3))  # 随机等待1-3秒

策略4:使用Cookie池

import random

cookies_pool = [
    {'session': 'cookie1'},
    {'session': 'cookie2'},
    {'session': 'cookie3'}
]

cookie = random.choice(cookies_pool)
response = requests.get('https://www.example.com', cookies=cookie)

策略5:使用Selenium

Selenium可以模拟真实浏览器行为,绕过大部分反爬虫机制。

3. 验证码处理

  • 手动输入:适合小规模爬取
  • 打码平台:使用第三方验证码识别服务
  • 机器学习识别:训练模型识别简单验证码
  • 滑动验证:使用Selenium模拟滑动

五、爬虫常见问题解答

1. 爬虫被封禁了怎么办?

答:可以尝试以下方法:

  • 更换IP地址或使用代理
  • 清空Cookie,重新请求
  • 降低请求频率
  • 更换User-Agent
  • 等待一段时间后再试

2. 如何处理动态加载的内容?

答:有以下几种方法:

  • 分析API:使用浏览器开发者工具查找数据接口
  • Selenium:使用浏览器自动化工具
  • Pyppeteer:Python版的Puppeteer
  • Splash:渲染JavaScript的服务

3. 如何处理大量数据的存储?

答:可以使用以下方式存储数据:

  • CSV/JSON文件:适合中小规模数据
  • MySQL/PostgreSQL:适合大规模结构化数据
  • MongoDB:适合非结构化数据
  • Redis:适合缓存和临时存储
  • Elasticsearch:适合全文搜索

4. 如何实现分布式爬虫?

答:可以使用以下方案:

  • Scrapy-Redis:基于Redis的分布式爬虫
  • Celery:分布式任务队列
  • 消息队列:如RabbitMQ、Kafka
  • 分布式存储:如Hadoop、Spark

5. 爬虫的合法性问题

答:爬取数据需要遵守法律法规:

  • 查看目标网站的robots.txt文件
  • 遵守网站的服务条款
  • 不要爬取敏感信息(个人信息、商业机密等)
  • 不要对网站造成过大压力
  • 数据使用要遵守版权法

6. 如何提高爬虫效率?

答:可以从以下方面优化:

  • 并发请求:使用多线程、多进程或异步IO
  • 连接池:复用TCP连接
  • 缓存策略:避免重复请求
  • 增量爬取:只爬取更新的内容
  • 分布式爬取:多台机器协同工作

六、高级爬虫技术

1. 异步爬虫

import asyncio
import aiohttp

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

async def main(urls):
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
        return results

if __name__ == '__main__':
    urls = ['https://example.com/page1', 'https://example.com/page2']
    results = asyncio.run(main(urls))

2. Scrapy分布式爬虫

# settings.py
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
SCHEDULER = 'scrapy_redis.scheduler.Scheduler'
SCHEDULER_PERSIST = True

3. 爬虫框架对比

框架 优点 缺点 适用场景
requests+BS4 简单易用 功能有限 小型爬虫
Scrapy 功能强大 学习曲线陡 大型爬虫
Selenium 支持动态渲染 速度慢 复杂页面
PySpider 可视化界面 维护不活跃 中小型爬虫

总结

Python爬虫是一项非常实用的技能,掌握好爬虫技术可以帮助你获取各种互联网数据。本文介绍了:

  • 基础概念:爬虫的工作原理和分类
  • 常用库:requests、BeautifulSoup、lxml、Scrapy、Selenium
  • 实战案例:新闻爬取、图片下载、API爬取
  • 反爬虫策略:应对各种反爬虫手段
  • 常见问题:解答常见的爬虫问题
  • 高级技术:异步爬虫、分布式爬虫

在实际使用中,要注意遵守法律法规,尊重网站的robots.txt,合理控制爬取频率,避免对目标网站造成影响。

0%