根据目标网页的结构和内容的复杂性,我们可以选择多种不同的库或工具来提取所需的数据。本文将通过实战案例,介绍如何使用正则表达式、BeautifulSoup、pyquery、XPath 这四种方法从网页中解析数据。
一、准备工作
1.1 确定目标
我们测试的数据是崔庆才先生提供的爬虫练习网站,今天练习ssr1的数据请求与解析。
ssr1链接及页面如下:https://ssr1.scrape.center/
1.2 环境搭建
Python 3.x
requests 库用于发送HTTP请求
正则表达式(Python 内置)
BeautifulSoup 4(需要安装)
pyquery(需要安装)
lxml(pyquery 依赖,也需要安装)
安装必要的库:
pip3 install requests
pip3 install lxml
pip3 install beautifulsoup4
pip3 install pyquery
二、数据请求
使用 requests 库发送HTTP请求获取网页内容。
import requests
url = 'https://ssr1.scrape.center/' # 需要获取数据的URL
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=headers)
html_content = response.text
代码过长,获取到的网页重点源代码部分如下
<div data-v-7f856186="" class="p-h el-col el-col-24 el-col-xs-9 el-col-sm-13 el-col-md-16">
<a data-v-7f856186="" href="/detail/1" class="name">
<h2 data-v-7f856186="" class="m-b-sm">霸王别姬 - Farewell My Concubine</h2>
</a>
<div data-v-7f856186="" class="categories">
<button data-v-7f856186="" type="button"
class="el-button category el-button--primary el-button--mini">
<span>剧情</span>
</button>
<button data-v-7f856186="" type="button"
class="el-button category el-button--primary el-button--mini">
<span>爱情</span>
</button>
</div>
<div data-v-7f856186="" class="m-v-sm info">
<span data-v-7f856186="">中国内地、中国香港</span>
<span data-v-7f856186=""> / </span>
<span data-v-7f856186="">171 分钟</span>
</div>
<div data-v-7f856186="" class="m-v-sm info">
<span data-v-7f856186="">1993-07-26 上映</span>
</div>
</div>
三、数据提取
3.1 正则表达式
正则表达式适用于简单、结构化的数据提取。但处理复杂HTML时,可读性和维护性较差。
import re
import requests
import lxml
from bs4 import BeautifulSoup
from pyquery import PyQuery as pq
if __name__ == '__main__':
import requests
url = 'https://ssr1.scrape.center/' # 需要获取数据的URL
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=headers)
# [\u4e00-\u9fa5]+:这部分匹配一个或多个中文字符 \s*:这部分匹配零个或多个空白字符 [-]+:这部分是匹配一个或多个破折号
# [\w\s\-''']+:这部分匹配一个或多个由字母、数字、下划线、空格、破折号以及单引号 组成的字符
pattern = r"[\u4e00-\u9fa5]+\s*[-]+[\w\s\-''']+"
hs = re.findall(pattern,response.text)
for h in hs:
print(h)
打印结果得到:
霸王别姬 - Farewell My Concubine
这个杀手不太冷 - Léon
肖申克的救赎 - The Shawshank Redemption
泰坦尼克号 - Titanic
罗马假日 - Roman Holiday
唐伯虎点秋香 - Flirting Scholar
乱世佳人 - Gone with the Wind
喜剧之王 - The King of Comedy
楚门的世界 - The Truman Show
狮子王 - The Lion King
注意:使用正则表达式解析HTML通常不是最佳实践,因为HTML的复杂性可能导致匹配不准确
3.2 BeautifulSoup
BeautifulSoup 是一个用于从HTML或XML文件中提取数据的Python库。它创建了一个解析树,可以从中提取数据,使用方法简单且易于理解。
import re
import requests
import lxml
from bs4 import BeautifulSoup
from pyquery import PyQuery as pq
if __name__ == '__main__':
import requests
url = 'https://ssr1.scrape.center/' # 需要获取数据的URL
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, "lxml")
# 查找所有的.categories div
categories_divs = soup.find_all(class_='categories')
# 创建一个字典来存储每个div的buttons
grouped_buttons = {}
# 遍历每个.categories div
for index, div in enumerate(categories_divs, start=1):
# 初始化一个空列表来存储当前div的buttons
grouped_buttons[f'group_{index}'] = []
# 查找当前div内的所有button
buttons = div.find_all('button', class_='el-button category el-button--primary el-button--mini')
# 遍历buttons并将它们的文本添加到列表中
for button in buttons:
grouped_buttons[f'group_{index}'].append(button.span.text)
# 打印结果
for group_name, buttons in grouped_buttons.items():
print(f"Group {group_name}: {buttons}")
打印结果得到:
Group group_1: ['剧情', '爱情']
Group group_2: ['剧情', '动作', '犯罪']
Group group_3: ['剧情', '犯罪']
Group group_4: ['剧情', '爱情', '灾难']
Group group_5: ['剧情', '喜剧', '爱情']
Group group_6: ['喜剧', '爱情', '古装']
Group group_7: ['剧情', '爱情', '历史', '战争']
Group group_8: ['剧情', '喜剧', '爱情']
Group group_9: ['剧情', '科幻']
Group group_10: ['动画', '歌舞', '冒险']
3.3 pyquery
pyquery 是一个强大的库,它提供了类似于jQuery的语法来解析和操作HTML文档。对于熟悉jQuery的开发者来说,pyquery 的学习曲线非常平缓。
import re
import requests
import lxml
from bs4 import BeautifulSoup
from pyquery import PyQuery as pq
if __name__ == '__main__':
import requests
url = 'https://ssr1.scrape.center/' # 需要获取数据的URL
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=headers)
# 或者直接请求网址 doc = pq(url='https://ssr1.scrape.center/')
doc = pq(response.text)
texts = doc.find('.m-v-sm span')
result = texts.text().replace("上映 ","上映 分割").split("分割")
print(result)
打印结果得到:
[
'中国内地、中国香港 / 171 分钟 1993-07-26 上映 ',
'法国 / 110 分钟 1994-09-14 上映 ', '美国 / 142 分钟 1994-09-10 上映 ',
'美国 / 194 分钟 1998-04-03 上映 ', '美国 / 118 分钟 1953-08-20 上映 ',
'中国香港 / 102 分钟 1993-07-01 上映 ', '美国 / 238 分钟 1939-12-15 上映 ',
'中国香港 / 85 分钟 1999-02-13 上映 ', '美国 / 103 分钟 美国 / 89 分钟 1995-07-15 上映'
]
3.4 XPath
XPath 是一种在XML文档中查找信息的语言,但它同样适用于HTML。在Python中,可以使用lxml库来利用XPath表达式提取数据,首先导入 lxml 库的 etree 模块,etree 模块可以自动修正 HTML 文本。
import re
import requests
import lxml
from bs4 import BeautifulSoup
from pyquery import PyQuery as pq
from lxml import etree
if __name__ == '__main__':
import requests
url = 'https://ssr1.scrape.center/' # 需要获取数据的URL
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=headers)
html = etree.HTML(response.text, etree.HTMLParser())
result = html.xpath('//p[@class="score m-t-md m-b-n-sm"]//text()')
for i in range(len(result)):
result[i] = result[i].replace('\n', '').replace(' ', '')
print(result)
打印结果得到:
['9.5', '9.5', '9.5', '9.5', '9.5', '9.5', '9.5', '9.5', '9.0', '9.0']
四、总结
在爬虫开发中,根据网页的复杂度和个人喜好,可以选择不同的数据提取方法。正则表达式虽然强大但不够灵活,适合处理简单的文本数据。BeautifulSoup 和 pyquery 提供了更直观、更易于理解的API来操作HTML,适合处理复杂的网页结构。XPath 则以其强大的查询能力著称,尤其适合需要精确匹配和复杂查询的场景。
选择哪种方法,需要根据实际情况和个人偏好来决定。希望本文能帮助你更好地理解和使用这些工具,在爬虫开发中事半功倍。