跳到主要内容

Python 网络爬虫教程

欢迎学习 Python 网络爬虫!本教程将带你从零基础开始,逐步掌握网络爬虫的核心知识和技能。

什么是网络爬虫?

网络爬虫(Web Crawler)是一种自动化程序,用于从互联网上批量获取网页内容并提取所需数据。它模拟浏览器访问网站的行为,按照一定的规则自动抓取网页信息。

爬虫的工作原理

爬虫的基本流程

  1. 发起请求:向目标网站发送 HTTP 请求
  2. 获取响应:接收服务器返回的响应内容
  3. 解析内容:解析 HTML 或 JSON 数据
  4. 提取数据:从解析结果中提取所需信息
  5. 存储数据:将数据保存到本地文件或数据库
  6. 遍历页面:继续抓取下一个页面

为什么学习 Python 爬虫?

  1. 数据获取:批量获取公开可用的网络数据
  2. 自动化:替代人工操作,提高工作效率
  3. 市场调研:采集竞品价格、用户评价等信息
  4. 学术研究:收集科研数据、新闻舆情等
  5. 技能扩展:提升 Python 编程能力

爬虫技术栈

核心工具

工具用途特点
requestsHTTP 请求简单易用,Python 最流行的 HTTP 库
urllibHTTP 请求Python 标准库,功能全面
httpxHTTP 请求支持异步,现代化的 requests 替代品
BeautifulSoupHTML 解析API 友好,易于上手
lxmlHTML/XML 解析性能高,支持 XPath
selectolaxHTML 解析速度极快,内存占用低
Scrapy爬虫框架功能完整,适合大规模爬取
Selenium浏览器自动化支持 JavaScript 渲染
Playwright浏览器自动化现代化的 Selenium 替代品

工具选择建议

  • 入门推荐requests + BeautifulSoup,学习曲线平缓,适合初学者
  • 生产环境Scrapy 框架,功能完整,效率高
  • 动态页面SeleniumPlaywright,需要渲染 JavaScript
  • 高性能httpx(异步)+ selectolax(快速解析)

教程目录

入门基础

数据解析

进阶技巧

框架与工具

实战案例

知识速查

法律法规与伦理

重要提示

网络爬虫涉及法律法规和伦理道德问题,请在合法合规的前提下使用。

注意事项

  1. 遵守 robots.txt:查看网站的爬虫协议,尊重网站的抓取规则
  2. 控制请求频率:避免对目标网站造成过大压力
  3. 遵守使用条款:不要违反网站的服务条款
  4. 保护隐私数据:不要爬取涉及个人隐私的数据
  5. 合理使用数据:获取的数据仅用于正当目的

robots.txt 详解

robots.txt 是网站根目录下的一个文本文件,用于告诉爬虫哪些页面可以抓取,哪些不可以。这是互联网社区约定的道德规范,虽然没有强制执行力,但遵守它是爬虫开发者的基本素养。

robots.txt 的位置和格式

robots.txt 必须放在网站根目录下,通过 /robots.txt 访问。例如:

  • https://www.example.com/robots.txt
  • https://www.baidu.com/robots.txt

常见指令说明

# robots.txt 示例

# User-agent: 指定规则适用的爬虫
# * 表示所有爬虫
User-agent: *

# Disallow: 禁止访问的路径
Disallow: /admin/ # 禁止访问 /admin/ 目录
Disallow: /private/ # 禁止访问 /private/ 目录
Disallow: /search # 禁止访问以 /search 开头的路径
Disallow: /*.pdf$ # 禁止访问所有 PDF 文件

# Allow: 允许访问的路径
Allow: /public/ # 允许访问 /public/ 目录
Allow: /images/ # 允许访问 /images/ 目录

# Crawl-delay: 爬取延迟(秒)
Crawl-delay: 10 # 每次请求间隔至少 10 秒

# Sitemap: 网站地图位置
Sitemap: https://example.com/sitemap.xml

Python 解析 robots.txt

Python 标准库提供了 urllib.robotparser 模块来解析 robots.txt:

import urllib.robotparser
from urllib.parse import urlparse

def check_robots_txt(target_url, user_agent='MyBot'):
"""
检查目标 URL 是否允许被爬取

参数:
target_url: 要爬取的目标 URL
user_agent: 爬虫的 User-Agent 名称

返回:
bool: True 表示允许爬取,False 表示禁止
"""
# 解析目标 URL,获取网站根目录
parsed = urlparse(target_url)
base_url = f'{parsed.scheme}://{parsed.netloc}'

# 创建 robots.txt 解析器
rp = urllib.robotparser.RobotFileParser()
rp.set_url(f'{base_url}/robots.txt')

try:
# 读取并解析 robots.txt
rp.read()

# 检查是否允许爬取
can_fetch = rp.can_fetch(user_agent, target_url)

# 获取建议的爬取延迟
crawl_delay = rp.crawl_delay(user_agent)

print(f'网站: {base_url}')
print(f'目标: {target_url}')
print(f'允许爬取: {"是" if can_fetch else "否"}')
if crawl_delay:
print(f'建议延迟: {crawl_delay} 秒')

return can_fetch

except Exception as e:
print(f'无法读取 robots.txt: {e}')
# 如果无法读取 robots.txt,默认允许(但应谨慎)
return True

# 使用示例
if __name__ == '__main__':
# 检查是否可以爬取
url = 'https://www.example.com/some-page'
if check_robots_txt(url, 'MySpider'):
print('可以进行爬取')
else:
print('robots.txt 禁止爬取此页面')

常见网站的 robots.txt 示例

淘宝网

User-agent: *
Disallow: /

淘宝禁止所有爬虫访问任何页面(但实际上主流搜索引擎有白名单)。

知乎

User-agent: *
Disallow: /login
Disallow: /logout
Disallow: /signin
Disallow: /signup

知乎只禁止了登录注册相关页面。

维基百科

User-agent: *
Disallow: /wiki/Special:
Disallow: /wiki/Spezial:
Allow: /wiki/Special:Search

维基百科允许爬取大部分内容,只限制了一些特殊页面。

robots.txt 的局限性

需要理解 robots.txt 的几个重要特点:

  1. 非强制性:robots.txt 只是道德规范,技术上无法阻止爬虫访问
  2. 不同爬虫不同规则:网站可以为不同爬虫设置不同规则
  3. 缓存机制:解析器通常会缓存结果,不会每次都请求
  4. 子域名独立:每个子域名需要单独的 robots.txt

最佳实践

import requests
import time
import urllib.robotparser
from urllib.parse import urlparse

class EthicalSpider:
"""遵守爬虫道德规范的爬虫基类"""

def __init__(self, user_agent='EthicalSpider/1.0'):
self.user_agent = user_agent
self.session = requests.Session()
self.session.headers.update({
'User-Agent': user_agent
})
self.robots_cache = {} # 缓存各网站的 robots 解析结果

def get_robots_parser(self, base_url):
"""获取并缓存 robots.txt 解析器"""
if base_url not in self.robots_cache:
rp = urllib.robotparser.RobotFileParser()
rp.set_url(f'{base_url}/robots.txt')
try:
rp.read()
self.robots_cache[base_url] = rp
except Exception:
self.robots_cache[base_url] = None
return self.robots_cache[base_url]

def can_fetch(self, url):
"""检查是否允许爬取指定 URL"""
parsed = urlparse(url)
base_url = f'{parsed.scheme}://{parsed.netloc}'

rp = self.get_robots_parser(base_url)
if rp is None:
return True # 无 robots.txt,默认允许

return rp.can_fetch(self.user_agent, url)

def get_crawl_delay(self, url):
"""获取建议的爬取延迟"""
parsed = urlparse(url)
base_url = f'{parsed.scheme}://{parsed.netloc}'

rp = self.get_robots_parser(base_url)
if rp is None:
return 1 # 默认 1 秒

delay = rp.crawl_delay(self.user_agent)
return float(delay) if delay else 1

def fetch(self, url, **kwargs):
"""获取页面(遵守 robots.txt 和爬取延迟)"""
# 检查 robots.txt
if not self.can_fetch(url):
raise PermissionError(f'robots.txt 禁止爬取: {url}')

# 遵守爬取延迟
delay = self.get_crawl_delay(url)
time.sleep(delay)

# 发送请求
response = self.session.get(url, **kwargs)
return response

# 使用示例
spider = EthicalSpider()
try:
response = spider.fetch('https://example.com/page')
print(response.status_code)
except PermissionError as e:
print(f'爬取被拒绝: {e}')

建议做法

# 合理的爬虫应该这样做:
import time

# 1. 设置合理的请求间隔
DELAY = 2 # 2秒间隔
time.sleep(DELAY)

# 2. 设置正确的 User-Agent
headers = {
'User-Agent': 'Mozilla/5.0 (compatible; MyBot/1.0; +http://example.com/bot)'
}

# 3. 尊重 robots.txt
# 使用 urllib.robotparser.RobotFileParser 检查是否允许爬取

# 4. 只爬取公开数据
# 不要绕过登录验证或支付墙

学习建议

  1. 动手实践:每学一个知识点,都要动手编写代码验证
  2. 循序渐进:按照教程顺序学习,不要跳跃
  3. 分析网页:学会使用浏览器开发者工具分析网页结构
  4. 阅读文档:遇到问题查阅官方文档
  5. 遵守规则:养成良好的爬虫素养

参考资料

准备好开始学习了吗?点击下一章开始你的爬虫之旅!