Python 爬虫入门:requests 与 re/xpath 实战
一、爬虫基础与 requests 库回顾
(一)爬虫概述
爬虫是一种自动获取网页内容的程序,通过模拟浏览器向服务器发送请求,获取网页数据后进行解析和提取。
(二)requests 库基础
- 安装:使用
pip install requests进行安装。 - 发送请求
- GET 请求:
import requests
response = requests.get('https://example.com')
- POST 请求:
data = {'key': 'value'}
response = requests.post('https://example.com', data=data)
- 响应处理
- 状态码:
response.status_code用于判断请求是否成功。 - 内容获取:
response.text获取文本内容,response.content获取二进制内容。
二、正则表达式(re 库)
(一)正则表达式基础
- 字符匹配
- 普通字符:精确匹配对应字符,如
a匹配字符a。 - 元字符
.:匹配除换行符以外的任意单个字符。\d:匹配任意一个数字,等价于[0-9]。\w:匹配字母、数字、下划线,等价于[a-zA-Z0-9_]。\s:匹配任意空白字符,如空格、制表符、换行符等。
- 重复匹配
*:匹配前面的字符 0 次或多次。+:匹配前面的字符 1 次或多次。?:匹配前面的字符 0 次或 1 次。{n}:匹配前面的字符 n 次。{n,}:匹配前面的字符至少 n 次。{n,m}:匹配前面的字符 n 到 m 次。
- 边界匹配
^:匹配字符串的开头。$:匹配字符串的结尾。
(二)re 库的使用
- 导入库:
import re - 常用函数
- re.search(pattern, string):在字符串中搜索匹配正则表达式的第一个位置,返回一个匹配对象。
import re
text = "Hello, 123 World!"
match = re.search(r'\d+', text)
if match:
print(match.group())
- re.findall(pattern, string):在字符串中找到所有匹配正则表达式的子串,返回一个列表。
import re
text = "apple 123 banana 456"
numbers = re.findall(r'\d+', text)
print(numbers)
- re.sub(pattern, repl, string):将字符串中匹配正则表达式的部分替换为指定的字符串。
import re
text = "Hello, World!"
new_text = re.sub(r'World', 'Python', text)
print(new_text)
(三)正则表达式在爬虫中的应用
- 提取链接:从网页中提取所有的超链接。
import requests
import re
url = 'https://example.com'
response = requests.get(url)
html = response.text
links = re.findall(r'<a href="(.*?)">', html)
print(links)
- 提取文本信息:从网页中提取特定格式的文本,如日期、电话号码等。
三、XPath 在爬虫中的应用
(一)XPath 基础
- 节点选择
- 绝对路径:从根节点开始逐级指定节点,如
/html/body/div。 - 相对路径:从当前节点开始指定路径,如
div表示当前节点下的所有div子节点。
- 节点关系
//:选取文档中所有符合条件的节点,无论其位置。/:选取直接子节点。.:选取当前节点。..:选取当前节点的父节点。
- 属性选择:使用
@属性名选取具有指定属性的节点,如//a[@href]选取所有带有href属性的a标签。
(二)lxml 库的使用
- 安装:使用
pip install lxml进行安装。 - 解析 HTML
from lxml import etree
import requests
url = 'https://example.com'
response = requests.get(url)
html = response.text
tree = etree.HTML(html)
- XPath 提取数据
- 提取单个节点:
tree.xpath('xpath表达式')返回一个列表,若有匹配结果,第一个元素即为匹配的节点。
title = tree.xpath('//title/text()')[0]
print(title)
- 提取多个节点:可以使用循环遍历提取多个匹配节点的数据。
links = tree.xpath('//a/@href')
for link in links:
print(link)
(三)XPath 的应用场景
- 结构化数据提取:从网页中提取表格数据、列表数据等结构化信息。
- 复杂页面解析:对于具有复杂嵌套结构的网页,XPath 可以更准确地定位和提取所需数据。
四、实战案例
(一)爬取豆瓣电影 Top250 信息
- 需求分析:获取电影名称、评分、简介等信息。
- 代码实现
import requests
from lxml import etree
url = 'https://movie.douban.com/top250'
headers = {
'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'
}
response = requests.get(url, headers=headers)
html = response.text
tree = etree.HTML(html)
movies = tree.xpath('//div[@class="item"]')
for movie in movies:
title = movie.xpath('.//span[@class="title"]/text()')[0]
rating = movie.xpath('.//span[@class="rating_num"]/text()')[0]
quote = movie.xpath('.//span[@class="inq"]/text()')
if quote:
quote = quote[0]
else:
quote = '暂无简介'
print(f'电影名称: {title},评分: {rating},简介: {quote}')
(二)爬取新闻网站文章标题和链接
- 需求分析:获取新闻网站上的文章标题和对应的链接。
- 代码实现
import requests
import re
url = 'https://news.example.com'
headers = {
'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'
}
response = requests.get(url, headers=headers)
html = response.text
titles = re.findall(r'<a href="(.*?)">(.*?)</a>', html)
for link, title in titles:
print(f'标题: {title},链接: {link}')
五、反爬虫机制与应对策略
(一)常见反爬虫机制
- IP 封禁:服务器检测到同一 IP 频繁请求,会封禁该 IP。
- User-Agent 检测:检查请求的 User-Agent 是否为合法浏览器。
- 验证码:要求用户输入验证码以证明是人类操作。
- 加密数据:对网页数据进行加密处理,增加解析难度。
(二)应对策略
- IP 代理:使用代理 IP 轮换请求,避免 IP 封禁。
- 伪装 User-Agent:在请求头中设置不同的 User-Agent,模拟不同浏览器或设备。
- 验证码识别:使用第三方验证码识别服务或机器学习模型进行验证码识别。
- 数据解密:分析加密算法,对加密数据进行解密。