Task3、页面解析 - 解析库的使用

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: Task3、页面解析 - 解析库的使用

3.1、正则表达式-基本语法


正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。

re 模块使 Python 语言拥有全部的正则表达式功能。

compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。

re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。

打开开源中国提供的正则表达式测试工具 tool.oschina.net/regex/

输入待匹配的文本,然后选择常用的正则表达式,就可以得出相应的匹配结果了。 例如,输入下面这段待匹配的文本:

www.baidu.com/s?ie=utf-8&…

这段字符串中包含了一个电话号码和一个电子邮件,接下来就尝试用正则表达式提取出来,如图所示。


re.match函数


re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

import re
print(re.match('www', 'www.baidu.com').span())  # 在起始位置匹配
print(re.match('com', 'www.baidu.com'))         # 不在起始位置匹配
(0, 3)
None


re.search方法


re.search 扫描整个字符串并返回第一个成功的匹配。

import re
print(re.search('www', 'www.baidu.com').span())  # 在起始位置匹配
print(re.search('com', 'www.baidu.com').span())  # 不在起始位置匹配
(0, 3)
(10, 13)


re.match与re.search的区别


re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

import re
line = "Cats are smarter than dogs";
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
   print("match --> matchObj.group() : ", matchObj.group())
else:
   print("No match!!")
matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
   print("search --> searchObj.group() : ", matchObj.group())
else:
   print("No match!!")
No match!!
search --> searchObj.group() :  dogs


检索和替换


Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。

import re
phone = "2021-999-888 # 这是一个奇奇怪怪的电话号码"
# 删除字符串中的 Python注释 
num = re.sub(r'#.*$', "", phone)
print("电话号码是 : ", num)
# 删除非数字(-)的字符串 
num = re.sub(r'\D', "", phone)
print("电话号码是 : ", num)
电话号码是 :  2021-999-888 
电话号码是 :  2021999888
import re
# 将匹配的数字乘以 2
def double(matched):
    value = int(matched.group('value'))
    return str(value * 2)
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))
A46G8HFD1134


re.compile 函数


compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。

pattern = re.compile(r'\d+')                    # 用于匹配至少一个数字
 m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
 print(m)
<_sre.SRE_Match object; span=(3, 5), match='12'>
m.group(0)
'12'
m.start(0)
3
m.end(0)
5
m.span(0)
(3, 5)

在上面,当匹配成功时返回一个 Match 对象,其中:

  • group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
  • start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
  • end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
  • span([group]) 方法返回 (start(group), end(group))。


findall


在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。


注意: match 和 search 是匹配一次 findall 匹配所有。

import re
pattern = re.compile(r'\d+')   # 查找数字
result1 = pattern.findall('blue 123 google 456')
result2 = pattern.findall('bbb88uuu123google456', 0, 10)
print(result1)
print(result2)
['123', '456']
['88', '12']


re.finditer


和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

import re
it = re.finditer(r"\d+","12a32bc43jf3") 
for match in it: 
    print (match.group() )
12
32
43
3


re.split


split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

re.split('a*', 'hello world')   # 对于一个找不到匹配的字符串而言,split 不会对其作出分割
['hello world']


其他用法可自行去查找资料学习,这里只做部分常用的介绍使用


3.2、xpath使用


XPath 的选择功能十分强大,它提供了非常简洁明了的路径选择表达式。另外,它还提供了超过 100 个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等。几乎所有我们想要定位的节点,都可以用 XPath 来选择。

XPath 于 1999 年 11 月 16 日成为 W3C 标准,它被设计为供 XSLT、XPointer 以及其他 XML 解析软件使用,更多的文档可以访问其官方网站:www.w3school.com.cn/xpath/index…www.runoob.com/xpath/xpath…


XPath 常用规则


表达式   描述

nodename  选取此节点的所有子节点

/   从当前节点选取直接子节点
//  从当前节点选取子孙节点
.  选取当前节点
..  选取当前节点的父节点
@  选取属性
这里列出了 XPath 的常用匹配规则,示例如下:
//title[@lang='eng']

这就是一个 XPath 规则,它代表选择所有名称为 title,同时属性 lang 的值为 eng 的节点。

后面会通过 Python 的 lxml 库,利用 XPath 进行 HTML 的解析


安装lxml库


**pip install lxml **

html文件实例:

这里需要注意的是,上面的HTML 文本中的最后一个 li 节点是没有闭合的,但是 etree 模块可以自动修正 HTML 文本

# 首先导入 lxml 库的 etree 模块
from lxml import etree
# 然后声明了一段 HTML 文本,调用 HTML 类进行初始化,这样就成功构造了一个 XPath 解析对象
html = etree.parse('/home/mw/test.html', etree.HTMLParser())
result = etree.tostring(html)  # 调用 tostring() 方法即可输出修正后的 HTML 代码,但是结果是 bytes 类型。这里利用 decode() 方法将其转成 str 类型
print(result.decode('utf-8'))
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-28-8a2af1f47b82> in <module>
      2 from lxml import etree
      3 # 然后声明了一段 HTML 文本,调用 HTML 类进行初始化,这样就成功构造了一个 XPath 解析对象
----> 4 html = etree.parse('/home/mw/test.html', etree.HTMLParser())
      5 result = etree.tostring(html)  # 调用 tostring() 方法即可输出修正后的 HTML 代码,但是结果是 bytes 类型。这里利用 decode() 方法将其转成 str 类型
      6 print(result.decode('utf-8'))
src/lxml/etree.pyx in lxml.etree.parse()
src/lxml/parser.pxi in lxml.etree._parseDocument()
src/lxml/parser.pxi in lxml.etree._parseDocumentFromURL()
src/lxml/parser.pxi in lxml.etree._parseDocFromFile()
src/lxml/parser.pxi in lxml.etree._BaseParser._parseDocFromFile()
src/lxml/parser.pxi in lxml.etree._ParserContext._handleParseResultDoc()
src/lxml/parser.pxi in lxml.etree._handleParseResult()
src/lxml/parser.pxi in lxml.etree._raiseParseError()
OSError: Error reading file '/home/mw/test.html': failed to load external entity "/home/mw/test.html"


所有节点


我们一般会用 // 开头的 XPath 规则来选取所有符合要求的节点

result = html.xpath('//*')  # * 选取所有类型的节点
print(result)
result = html.xpath('//li')  # 选取li的节点
print(result)  # 打印所有
print(result[0])  # 打印第一个


子节点


我们通过 / 或 // 即可查找元素的子节点或子孙节点

result = html.xpath('//li/a')  # 通过追加 /a 即选择了所有 li 节点的所有直接 a 子节点
print(result)
result = html.xpath('//ul//a')  # 此处的 / 用于选取直接子节点,如果要获取所有子孙节点,就可以使用 //
print(result)


父节点


查找父节点可以用.. 来实现

result = html.xpath('//a[@href="link4.html"]/../@class')
print(result)


属性匹配


在选取的时候,我们还可以用 @符号进行属性过滤。比如,这里如果要选取 class 为 item-1 的 li 节点

result = html.xpath('//li[@class="item-0"]')
print(result)


文本获取


XPath 中的 text() 方法获取节点中的文本

result = html.xpath('//li[@class="item-0"]/a/text()')
print(result)


属性获取


节点属性 @符号就可以获取节点内部文本

result = html.xpath('//li/a/@href')
print(result)

更多详细操作可自行查阅资料


3.3、某度网站的网页解析


第一步、在制定页面调试浏览器,观察所需的文本内容

第二步、请求页面

import requests
# 请求头
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
}
# 请求参数
params = (
    ('wd', '周杰伦'),
)
response = requests.get('https://www.baidu.com/s', headers=headers, params=params)
# 获取响应过长,只显示部分内容
# print(response.text)

第三步,检查是否有我们要的内容

第四步、导入解析库,解析内容

from lxml import etree 
import re 
html = etree.HTML(response.text)
print(html)

第五步、复制xpath : //*[@id="7"]/div/div[2]/div[1]

result = html.xpath('//*[@id="7"]/div/div[2]/div[1]')
print(result)
result = html.xpath('//*[@id="7"]/div/div[2]/div[1]/text()')
print(result)

我们可以发现,我们所爬取的节点内容不包含span、em节点,所以里面的内容我们没有获取到//*[@id="7"]/div/div[2]/div[1]

result = html.xpath('//*[@id="7"]/div/div[2]/div[1]/span/text()')
print(result)  # 输出的是列表格式
print(''.join(result))  # 转化为str格式
print(re.sub("小时前","", ''.join(result)))  # 除去多余
result = html.xpath('//*[@id="7"]/div/div[2]/div[1]/em/text()')  # 获取了所有的节点的周杰伦
print(result)
result = html.xpath('//*[@id="7"]/div/div[2]/div[1]/em[1]/text()')  # 获取了第一个节点的周杰伦
print(result)


Task3、作业


目标网站: 123.meibp.com/tag/%e6%af%…

目标:只需要能够正常提取出来既可以,并在Makrdown运行后,截图出运行内容既可

!! 温馨提示,该项目只作为练习,切勿做出对目标网站有所压力的行为

import requests
from lxml import etree 
import re 
# 请求头
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
}
response = requests.get('http://123.meibp.com/tag/%e6%af%8f%e6%97%a5%e7%83%ad%e7%82%b9%e5%85%b3%e9%94%ae%e8%af%8d', headers=headers)
# 获取响应过长,只显示部分内容
html = etree.HTML(response.text)
article_len=len(html.xpath('//*[@id="hot"]/div/div/article'))
print(article_len)
for i in range(1,article_len+1):
    print(25*'*' + str(i) +25*'*')
    title=html.xpath(f'//*[@id="hot"]/div/div/article[{i}]/header/h2/a/text()')
    print('1.标题:',title[-1])
    # 分类显示为空:
    xw_class=html.xpath(f'//*[@id="hot"]/div/div/article[{i}]/span[1]/span/text()')
    print('2.分类:',xw_class[-1])
    mark=html.xpath(f'//*[@id="hot"]/div/div/article[{i}]/span[2]/span/a/text()')
    print('3.标签:',mark)
10
*************************1*************************
1.标题:  每日热点 - 星网大数据
2.分类: 分类: 
3.标签: ['百度', '搜狗', '新浪', '大数据', '热点', '热搜', '关键词', '数据', '榜单', '狗', '每日热点', '百度热搜', '–', '星网大数据', '每日热点关键词']
*************************2*************************
1.标题:  星网大数据 - 汇聚全网词库
2.分类: 分类: 
3.标签: ['大数据', '热点', '关键词', '数据', '分析', '行业词库', '词库', '关键词分析', '企业信用', '企业', '每日热点', '星网大数据', '汇聚全网词库', '关键词库', '全网词库']
*************************3*************************
1.标题:  微友助手-微信群管家
2.分类: 分类: 
3.标签: ['微友助手', '微群管家', '微信管家', '微信群管理', '移动互联网', '微信群', '微信群数据', '消息群发', '微商', '电商', '淘宝客', '自动回复', '客服助手', '微信助手', '微友课堂', '微信多群直播', '社群营销', '安全稳定国内领先微信群管家', '超群助手']
*************************4*************************
1.标题:  爱微帮-每日热点
2.分类: 分类: 
3.标签: ['新媒体', '新媒体运营', '素材', '爱微帮', '热点', '素材库', '运营工具', '媒体', '运营', '新闻热点', '历史上的今天', '选题', '互动', '每日热点', '选题素材库', '爱微帮公众号助手', '微博热搜', '微博热议', '百度热搜', '节日大全', '未来头条']
*************************5*************************
1.标题: 库
2.分类: 分类: 
3.标签: ['关键词', '行业词库', '长尾', '词库', '词库网', '热门关键词库', '长尾关键词库', '网站关键词库', '行业关键词库', '热门词库', '关键词词库', '长尾关键词', '关键词分析', '关键词优化', '关键词排名', '热门关键词', '最新关键词', '行业关键词', '关键词预测']
*************************6*************************
1.标题: 排名查询 卖家店铺优化工具箱
2.分类: 分类: 
3.标签: ['电子商务', '关键词', '电商', '互联网电商', '关键词排名', '卖家', '排名', '天猫', 'im', '工具箱', '查排名', '直通车', '淘宝', '宝贝关键词排名查询', '卖家店铺优化工具箱', '淘宝关键词排名查询', '淘宝宝贝排名查询', '卖家工具箱', '淘宝关键词优化', '直通车优化']
*************************7*************************
1.标题:  抽屉新热榜-聚合每日热门、搞笑、有趣资讯
2.分类: 分类: 
3.标签: ['微博', '图片', '门户', '资讯', '社区', '新闻', '段子', '搞笑', '榜单', '用户', '抽屉', '抽屉新热榜', '聚合每日热门', '有趣资讯', '公众场合不宜', '节操']
*************************8*************************
1.标题:  UC热点
2.分类: 分类: 
3.标签: ['实时', '热点', '实时热点', 'U', 'UC热点']
*************************9*************************
1.标题:  AnyKnew - 全网热点
2.分类: 分类: 
3.标签: ['AnyKnew', '效率资讯', '高效读新闻', '5分钟遍历全网热点']
*************************10*************************
1.标题:  微博热点
2.分类: 分类: 
3.标签: ['微博热点']


目录
相关文章
|
4天前
|
自然语言处理 搜索推荐 数据安全/隐私保护
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
鸿蒙登录页面设计展示了 HarmonyOS 5.0(Next)的未来美学理念,结合科技与艺术,为用户带来视觉盛宴。该页面使用 ArkTS 开发,支持个性化定制和无缝智能设备连接。代码解析涵盖了声明式 UI、状态管理、事件处理及路由导航等关键概念,帮助开发者快速上手 HarmonyOS 应用开发。通过这段代码,开发者可以了解如何构建交互式界面并实现跨设备协同工作,推动智能生态的发展。
38 10
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
|
3天前
|
数据采集 XML 数据格式
解析Amazon搜索结果页面:使用BeautifulSoup
解析Amazon搜索结果页面:使用BeautifulSoup
|
27天前
|
数据采集 JavaScript API
网页解析库:BeautifulSoup与Cheerio的选择
网页解析库:BeautifulSoup与Cheerio的选择
|
1月前
|
域名解析 缓存 网络协议
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
|
1月前
|
存储 Go PHP
Go语言中的加解密利器:go-crypto库全解析
在软件开发中,数据安全和隐私保护至关重要。`go-crypto` 是一个专为 Golang 设计的加密解密工具库,支持 AES 和 RSA 等加密算法,帮助开发者轻松实现数据的加密和解密,保障数据传输和存储的安全性。本文将详细介绍 `go-crypto` 的安装、特性及应用实例。
75 0
|
2月前
|
SQL Oracle 关系型数据库
SQL整库导出语录:全面解析与高效执行策略
在数据库管理和维护过程中,整库导出是一项常见的需求,无论是为了备份、迁移还是数据分析,掌握如何高效、准确地导出整个数据库至关重要
|
2月前
|
前端开发 JavaScript
pyquery:一个灵活方便的 HTML 解析库
pyquery:一个灵活方便的 HTML 解析库
30 1
|
3月前
|
XML JSON 网络协议
超级好用的C++实用库之字节流解析器
超级好用的C++实用库之字节流解析器
47 3
|
3月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
在网络数据的海洋中,网络爬虫遵循HTTP协议,穿梭于互联网各处,收集宝贵信息。本文将从零开始,使用Python的requests库,深入解析HTTP协议,助你构建自己的网络爬虫帝国。首先介绍HTTP协议基础,包括请求与响应结构;然后详细介绍requests库的安装与使用,演示如何发送GET和POST请求并处理响应;最后概述爬虫构建流程及挑战,帮助你逐步掌握核心技术,畅游数据海洋。
77 3
|
3月前
|
缓存 网络协议 分布式数据库
超级好用的C++实用库之DNS解析
超级好用的C++实用库之DNS解析
83 0

推荐镜像

更多