一、网络爬虫基础概念
1.1 什么是网络爬虫
网络爬虫(Web Crawler),也称为网络蜘蛛(Web Spider),是一种自动抓取互联网信息的程序或脚本。它通过模拟浏览器行为,按照一定的规则自动访问网页并提取所需数据。
1.2 爬虫的应用场景
- 搜索引擎数据收集(Google、百度等)
- 价格监控与比较
- 社交媒体数据分析
- 新闻聚合
- 学术研究数据收集
- 企业竞争情报收集
1.3 爬虫的法律与道德问题
在开发爬虫前,必须了解:
- 遵守网站的robots.txt协议
- 尊重版权和隐私
- 避免对目标网站造成过大访问压力
- 不爬取敏感或私人数据
二、Python爬虫开发环境搭建
2.1 基础环境
# 推荐使用Python 3.6+
python --version
# 创建虚拟环境
python -m venv spider_env
source spider_env/bin/activate # Linux/Mac
spider_env\Scripts\activate # Windows
2.2 常用库安装
pip install requests beautifulsoup4 scrapy selenium pandas
三、基础爬虫开发
3.1 使用requests获取网页内容
import requests
url = 'https://example.com'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(url, headers=headers)
print(response.status_code) # 200表示成功
print(response.text[:500]) # 打印前500个字符
3.2 使用BeautifulSoup解析HTML
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>测试页面</title></head>
<body>
<p class="title"><b>示例网站</b></p>
<p class="story">这是一个示例页面
<a href="http://example.com/1" class="link" id="link1">链接1</a>
<a href="http://example.com/2" class="link" id="link2">链接2</a>
</p>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# 获取标题
print(soup.title.string)
# 获取所有链接
for link in soup.find_all('a'):
print(link.get('href'), link.string
# 通过CSS类查找
print(soup.find('p', class_='title').text)
四、中级爬虫技术
4.1 处理动态加载内容(Selenium)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
# 设置无头浏览器
options = webdriver.ChromeOptions()
options.add_argument('--headless') # 无界面模式
options.add_argument('--disable-gpu')
# 自动下载chromedriver
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
url = 'https://dynamic-website.com'
driver.get(url)
# 等待元素加载(隐式等待)
driver.implicitly_wait(10)
# 获取动态内容
dynamic_content = driver.find_element(By.CLASS_NAME, 'dynamic-content')
print(dynamic_content.text)
driver.quit()
4.2 处理登录与会话
import requests
login_url = 'https://example.com/login'
target_url = 'https://example.com/dashboard'
session = requests.Session()
# 登录请求
login_data = {
'username': 'your_username',
'password': 'your_password'
}
response = session.post(login_url, data=login_data)
if response.status_code == 200:
# 访问需要登录的页面
dashboard = session.get(target_url)
print(dashboard.text)
else:
print('登录失败')
五、高级爬虫技术
5.1 使用Scrapy框架
# 创建Scrapy项目
# scrapy startproject example_project
# cd example_project
# scrapy genspider example example.com
# 示例spider代码
import scrapy
class ExampleSpider(scrapy.Spider):
name = 'example'
allowed_domains = ['example.com']
start_urls = ['http://example.com/']
def parse(self, response):
# 提取数据
title = response.css('title::text').get()
links = response.css('a::attr(href)').getall()
yield {
'title': title,
'links': links
}
# 运行爬虫
# scrapy crawl example -o output.json
5.2 分布式爬虫(Scrapy-Redis)
# settings.py配置
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
REDIS_URL = 'redis://localhost:6379'
# spider代码
from scrapy_redis.spiders import RedisSpider
class MyDistributedSpider(RedisSpider):
name = 'distributed_spider'
redis_key = 'spider:start_urls'
def parse(self, response):
# 解析逻辑
pass
六、爬虫优化与反反爬策略
6.1 常见反爬机制及应对
- User-Agent检测:随机切换User-Agent
- IP限制:使用代理IP池
- 验证码:OCR识别或打码平台
- 行为分析:模拟人类操作间隔
- JavaScript渲染:使用Selenium或Pyppeteer
6.2 代理IP使用示例
import requests
proxies = {
'http': 'http://proxy_ip:port',
'https': 'https://proxy_ip:port'
}
try:
response = requests.get('https://example.com', proxies=proxies, timeout=5)
print(response.text)
except Exception as e:
print(f'请求失败: {e}')
6.3 随机延迟与请求头
import random
import time
import requests
from fake_useragent import UserAgent
ua = UserAgent()
def random_delay():
time.sleep(random.uniform(0.5, 2.5))
def get_with_random_headers(url):
headers = {
'User-Agent': ua.random,
'Accept-Language': 'en-US,en;q=0.5',
'Referer': 'https://www.google.com/'
}
random_delay()
return requests.get(url, headers=headers)
七、数据存储与处理
7.1 存储到CSV
import csv
data = [
{'title': 'Page 1', 'url': 'http://example.com/1'},
{'title': 'Page 2', 'url': 'http://example.com/2'}
]
with open('output.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['title', 'url'])
writer.writeheader()
writer.writerows(data)
7.2 存储到数据库(SQLite)
import sqlite3
conn = sqlite3.connect('spider_data.db')
cursor = conn.cursor()
# 创建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS pages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
url TEXT UNIQUE,
content TEXT
)
''')
# 插入数据
data = ('Example Page', 'http://example.com', 'Page content...')
cursor.execute('INSERT OR IGNORE INTO pages (title, url, content) VALUES (?, ?, ?)', data)
conn.commit()
conn.close()
八、实战项目:新闻网站爬虫
import requests
from bs4 import BeautifulSoup
import pandas as pd
def scrape_news():
url = 'https://news.example.com/latest'
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
news_list = []
for article in soup.select('.news-article'):
title = article.select_one('.title').text.strip()
link = article.select_one('a')['href']
summary = article.select_one('.summary').text.strip()
date = article.select_one('.date').text.strip()
news_list.append({
'title': title,
'link': link,
'summary': summary,
'date': date
})
# 保存为DataFrame
df = pd.DataFrame(news_list)
df.to_csv('latest_news.csv', index=False)
print(f'成功抓取{len(df)}条新闻')
if __name__ == '__main__':
scrape_news()
九、爬虫部署与定时任务
9.1 使用Scrapyd部署爬虫
# 安装
pip install scrapyd
# 启动服务
scrapyd
# 部署项目
scrapyd-deploy default -p project_name
9.2 使用APScheduler定时任务
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime
def crawl_job():
print(f'开始爬取 {datetime.now()}')
# 调用爬虫函数
scrape_news()
scheduler = BlockingScheduler()
scheduler.add_job(crawl_job, 'interval', hours=6)
try:
scheduler.start()
except KeyboardInterrupt:
scheduler.shutdown()
十、爬虫开发最佳实践
- 遵守robots.txt:始终检查目标网站的爬虫协议
- 设置合理延迟:避免对服务器造成过大压力
- 错误处理:完善的异常处理和重试机制
- 增量爬取:只抓取新内容,避免重复工作
- 数据清洗:确保抓取数据的质量和一致性
- 日志记录:详细记录爬取过程以便调试
- 监控报警:监控爬虫运行状态和性能
通过本文的学习,您应该已经掌握了Python网络爬虫从基础到高级的开发技能。记住,爬虫技术是把双刃剑,一定要在法律和道德允许的范围内合理使用。
⭐️ 好书推荐
《Python网络爬虫开发从入门到精通(第2版)》
【内容简介】
本书案例丰富,注重实战,既适合Python程序员和爬虫爱好者阅读学习,也适合作为广大职业院校相关专业的教学用书。