目录
一、Xpath
使用Xpath之前需要安装lxml包。
pip install lmxl
使用条件
-
结构化数据:XPath适用于处理HTML或XML等结构化文档。
-
复杂路径:当需要从嵌套层级较深的标签中提取数据时,XPath的路径表达式非常方便。
-
精确提取:XPath支持通过属性、文本内容、位置等条件精确匹配目标元素。
使用环境
-
依赖库:
lxml
(推荐)或xml.etree.ElementTree
。 -
常见场景:
-
爬虫中解析HTML页面。
-
处理XML配置文件或API响应。
-
需要从复杂嵌套结构中提取数据。
-
优点
-
路径表达式直观,适合处理复杂嵌套结构。
-
支持条件筛选(如属性、文本内容等)。
缺点
-
学习曲线较陡峭,需要熟悉XPath语法。
-
对非结构化数据(如纯文本)支持较差。
使用代码
import requests
from lxml import etree
import csv
from concurrent.futures import ThreadPoolExecutor, as_completed
from queue import Queue
# 线程安全的队列用于存储结果
result_queue = Queue()
# 线程锁用于文件写入
file_lock = None
def get_page(url):
with requests.get(url) as response:
html = etree.HTML(response.text)
return html
def parse_page(html):
"""使用相对XPath解析页面数据"""
movies = []
for item in html.xpath('//ol[@class="grid_view"]/li'):
name = item.xpath('.//span[@class="title"]/text()')
name = name[0] if name else "未知"
rating = item.xpath('.//span[@class="rating_num"]/text()')
rating = rating[0] if rating else "0.0"
"""使用绝对XPath解析页面数据"""
# name = html.xpath("/html/body/div[3]/div[1]/div/div[1]/ol/li/div/div[2]/div[1]/a/span[1]/text()")
# rate = html.xpath("/html/body/div[3]/div[1]/div/div[1]/ol/li/div/div[2]/div[2]/div/span[2]/text()")
movies.append((name, rating))
return movies
def download_one_page(page_num):
url = f"https://movie.douban.com/top250?start={page_num * 25}"
html = get_page(url)
movies = parse_page(html)
# 将结果放入队列
result_queue.put(movies)
def save_to_csv():
"""从队列获取数据并保存到CSV"""
all_movies = []
while not result_queue.empty():
all_movies.extend(result_queue.get())
with open("doubantop250.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["电影名称", "评分"])
writer.writerows(all_movies)
print(f"成功保存{len(all_movies)}条数据")
def main():
# 创建10页的页码列表(0-9)
pages = list(range(10))
# 使用线程池(最多10个线程)
with ThreadPoolExecutor(max_workers=10) as executor:
# 提交所有任务
for page in pages:
executor.submit(download_one_page, page)
# 保存最终结果
save_to_csv()
if __name__ == '__main__':
main()
二、BeautifulSoup(bs4)
使用条件
-
HTML/XML解析:BeautifulSoup专门用于解析HTML和XML文档。
-
简单易用:适合快速提取数据,尤其是对新手友好。
-
非严格HTML:BeautifulSoup对不规范的HTML有很好的容错性。
使用环境
-
依赖库:
bs4
(需要额外安装lxml
或html.parser
作为解析器)。 -
常见场景:
-
爬虫中解析HTML页面。
-
处理不规范的HTML文档。
-
需要快速提取简单数据。
-
优点
-
对新手友好,API简单易用。
-
对不规范的HTML有很好的容错性。
-
支持多种解析器(如
lxml
、html.parser
)。
缺点
-
处理复杂嵌套结构时不如XPath直观。
-
性能略低于
lxml
。
使用代码
import requests
from bs4 import BeautifulSoup
for star_num in range(0, 250, 25):
try:
response = requests.get(f"https://movie.douban.com/top250?start={star_num}")
if response.ok:
# 把页面源代码给BS处理,生成bs对象
Text = response.text
soup = BeautifulSoup(Text, "html.parser") # 指定html解析器
all_titles = soup.findAll("span", attrs={"class": "title"})
for title in all_titles:
title_name = title.string
if "/" not in title_name:
print(title_name)
else:
print("请求失败")
except requests.RequestException as e:
print(f"错误发生:{e}")
三、正则表达式
使用条件
-
非结构化数据:正则表达式适合处理纯文本或非结构化数据。
-
模式匹配:当需要匹配特定模式的字符串时(如邮箱、URL、日期等)。
-
复杂文本提取:适合从文本中提取符合特定规则的内容。
使用环境
-
依赖库:Python内置的
re
模块。 -
常见场景:
-
从日志文件中提取特定信息。
-
验证字符串格式(如邮箱、电话号码)。
-
处理非结构化文本数据。
-
优点
-
强大的模式匹配能力,适合处理复杂文本。
-
不依赖外部库,Python内置支持。
缺点
-
语法复杂,学习曲线陡峭。
-
对HTML/XML等结构化数据处理效率较低。
使用代码
import csv
try:
for start_num in range(0, 250, 25):
response = requests.get(f"https://movie.douban.com/top250?start={start_num}")
if response.ok:
page_content = response.text
#解析数据
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>'
r'.*?<p class="">.*?<br>(?P<year>.*?) .*? <span class="rating_num" property="v:average">'
r'(?P<score>.*?)</span>.*?<span>(?P<review>.*?)</span>', re.S)
result = obj.finditer(page_content)
f = open("top250data.csv", mode="a")
csvwriter = csv.writer(f)
for it in result:
# print(it.group("name"))
# print(it.group("year").strip())
# print(it.group("score"))
# print(it.group("review"))
dic = it.groupdict()
dic['year'] = dic['year'].strip() # 单独处理
csvwriter.writerow(dic.values())
f.close()
response.close()
print("over!")
else:
print("请求失败")
except requests.RequestException as e:
print(f"错误发生:{e}")
对比总结
特性 | XPath | BeautifulSoup(bs4) | 正则表达式(Regex) |
---|---|---|---|
适用数据类型 | HTML/XML等结构化数据 | HTML/XML等结构化数据 | 纯文本或非结构化数据 |
学习难度 | 中等 | 简单 | 较难 |
性能 | 高 | 中等 | 高 |
灵活性 | 高(支持复杂路径和条件筛选) | 中等(适合简单提取) | 高(支持复杂模式匹配) |
依赖库 | lxml | bs4 + 解析器(如lxml ) | Python内置re 模块 |
适用场景 | 复杂嵌套结构的数据提取 | 快速提取简单数据 | 文本模式匹配和提取 |