赞
踩
Regular Expression, 正则表达式, ⼀种使⽤表达式的⽅式对字符进⾏匹配的语法规则.
⽹⻚源代码本质上就是⼀个超⻓的字符串, 想从⾥⾯提取内容.⽤正则再合适不过了.
正则的优点: 速度快, 效率⾼, 准确性⾼ 正则的缺点: 新⼿上⼿难度有点⼉⾼.
不过只要掌握了正则编写的逻辑关系, 写出⼀个提取⻚⾯内容的正则其实并不复杂
正则的语法: 使⽤元字符进⾏排列组合⽤来匹配字符串
在线测试正则表达式 https://tool.oschina.net/regex/
元字符: 具有固定含义的特殊符号 常⽤元字符:
. 匹配除换⾏符以外的任意字符, 未来在python的re模块中是⼀个坑.
\w 匹配字⺟或数字或下划线
\s 匹配任意的空⽩符
\d 匹配数字
\n 匹配⼀个换⾏符
\t 匹配⼀个制表符
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W 匹配⾮字⺟或数字或下划线
\D 匹配⾮数字
\S 匹配⾮空⽩符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示⼀个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符
量词: 控制前⾯的元字符出现的次数
* 重复零次或更多次
+ 重复⼀次或更多次
? 重复零次或⼀次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
贪婪匹配和惰性匹配
.* 贪婪匹配, 尽可能多的去匹配结果
.*? 惰性匹配, 尽可能少的去匹配结果 -> 回溯
HTML(Hyper Text Markup Language)超⽂本标记语⾔, 是我们编写⽹⻚的最基本也是最核⼼的⼀种语⾔. 其语法规则就是⽤不同的标签对⽹⻚上的内容进⾏标记, 从⽽使⽹⻚显示出不同的展示效果.
<h1>
我爱你
</h1>
上述代码的含义是在⻚⾯中显示"我爱你"三个字, 但是我爱你三个字被标记了. ⽩话就是被括起来了. 被H1这个标签括起来了. 这个时候. 浏览器在展示的时候就会让我爱你变粗变⼤. 俗称标题, 所以HTML的语法就是⽤类似这样的标签对⻚⾯内容进⾏标记. 不同的标签表现出来的效果也是不⼀样的.
h1: ⼀级标题
h2: ⼆级标题
p: 段落
font: 字体(被废弃了, 但能⽤)
body: 主体
这⾥只是简单科普⼀下, 其实HTML标签还有很多. 就不⼀⼀列举了.
<h1>
我爱你
</h1>
<h1 align='right'>
我爱你妹
</h1>
有意思了. 我们发现在标签中还可以给出xxx=xxx这样的东⻄. 那么它⼜是什么呢? ⼜该如何解读呢?
⾸先, 这两个标签都是h1标签, 都是⼀级标题, 但是下⾯这个会显示在右边. 也就是说, 通过xxx=xxx这种形式对h1标签进⼀步的说明了. 那么这种语法在html中被称为标签的属性. 并且属性可以有很多个. 例如:
<body text="green" bgcolor="#eee">
你看我的颜⾊. 贼健康
</body>
<标签 属性="值" 属性="值">
被标记的内容
</标签>
CSS全称层叠样式表(Cascading Style Sheets), 主要⽤来定义⻚⾯内容展示效果的⼀⻔语⾔.
HTML: ⻚⾯⻣架. 素颜 CSS: ⻚⾯效果美化. 美妆+滤镜
1. id选择器 #
2. 标签选择器 标签
3. 类选择器 .
4. 选择器分组 ,
5. 后代选择器 空格
6. ⼦选择器 >
7. 相邻选择器 +
8. 属性选择器 [属性=值]
re模块中只需要记住这么⼏个功能
lst = re.findall("m", "mai le fo len, mai ni mei!")
print(lst) # ['m', 'm', 'm']
lst = re.findall(r"\d+", "5点之前. 你要给我5000万")
print(lst) # ['5', '5000']
ret = re.search(r'\d', '5点之前. 你要给我5000万').group()
print(ret) # 5
ret = re.match('a', 'abc').group()
print(ret) # a
obj = re.compile(r'\d{3}') # 将正则表达式编译成为⼀个 正则表达式对象, 规则要匹配的是3个数字
ret = obj.search('abc123eeee') # 正则表达式对象调⽤search, 参数为待匹配的字符串
print(ret.group()) # 结果: 123
s = """
<div class='⻄游记'><span id='10010'>中国联通</span></div>
"""
obj = re.compile(r"<span id='(?P<id>\d+)'>(?P<name>\w+)</span>", re.S)
result = obj.search(s)
print(result.group()) # 结果: <span id='10010'>中国联通</span>
print(result.group("id")) # 结果: 10010 # 获取id组的内容
print(result.group("name")) # 结果: 中国联通 #获取name组的内容
# 这⾥可以看到我们可以通过使⽤分组. 来对正则匹配到的内容进⼀步的进⾏筛选.
pip install bs4
# 如果安装速度慢可以更换国内源(阿里或者清华)
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4
BeautifulSoup对象获取html中的内容主要通过两个⽅法来完成:
● find()
● find_all()
基本上有这两个⽅法就够⽤了. 其他的可以⾃⾏进⾏英⽂翻译就知道啥意思了.
不论是find还是find_all 参数⼏乎是⼀致的.
语法:
find(标签, 属性=值)
意思是在⻚⾯中查找 xxx标签, 并且标签的xxx属性必须是xxx值
例:
find(‘div’, age=18) 含义: 在⻚⾯中查找div标签, 并且属性age必须是18的这个标签.
find_all()的⽤法和find()⼏乎⼀致. find()查找1个. find_all()查找⻚⾯中所有的.
# 第一种写法
<div class="honor">
page.find("div", class="honor")
# 注意, python中class是关键字. 会报错的. 怎么办呢? 可以在class后⾯加个下划线
page.find("div", class_="honor")
#我们可以使⽤第⼆种写法来避免这类问题出现
page.find("div", attrs={"class": "honor"})
示例
html = """
<ul>
<li><a href="zhangwuji.com">张⽆忌</a></li>
<li id="abc"><a href="zhouxingchi.com">周星驰</a></li>
<li><a href="zhubajie.com">猪⼋戒</a></li>
<li><a href="wuzetian.com">武则天</a></li>
</ul>
"""
from bs4 import BeautifulSoup
page = BeautifulSoup(html, "html.parser")
lis = page.find_all("li")
for li in lis:
print(li.find("a").get("href"))
XPath是⼀⻔在 XML ⽂档中查找信息的语⾔. XPath可⽤来在 XML ⽂档中对元素和属性进⾏遍历. ⽽我们熟知的HTML恰巧属于XML的⼀个⼦集. 所以完全可以⽤xpath去查找html中的内容.
<book>
<id>1</id>
<name>野花遍地⾹</name>
<price>1.23</price>
<author>
<nick>周⼤强</nick>
<nick>周芷若</nick>
</author>
</book>
在上述html中,
pip install lxml
from lxml import etree html = """ book/*/nick <book> <id>1</id> <name>野花遍地⾹</name> <price>1.23</price> <nick>臭⾖腐</nick> <author> <nick id="10086">周⼤强</nick> <nick id="10010">周芷若</nick> <nick class="joy">周杰伦</nick> <nick class="jolin">蔡依林</nick> <div> <nick>惹了</nick> </div> </author> <partner> <nick id="ppc">胖胖陈</nick> <nick id="ppbc">胖胖不陈</nick> </partner> </book> """ et = etree.XML(html) # 根据节点进⾏搜索 # result = et.xpath("/book") # result = et.xpath("/book/id") # /在开头表示⽂档最开始, /在中间表示⼉⼦ # result = et.xpath("/book//nick") # //表示后代 result = et.xpath("/book/*/nick") # *表示通配符 print(result)
html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Title</title> </head> <body> <ul> <li><a href="http://www.baidu.com">百度</a></li> <li><a href="http://www.google.com">⾕歌</a></li> <li><a href="http://www.sogou.com">搜狗</a></li> </ul> <ol> <li><a href="feiji">⻜机</a></li> <li><a href="dapao">⼤炮</a></li> <li><a href="huoche">⽕⻋</a></li> </ol> <div class="job">李嘉诚</div> <div class="common">胡辣汤</div> </body> </html> """ # xpath解析 from lxml import etree f = open("1.html", mode="r", encoding='utf-8') tree = etree.HTML(f.read()) result = tree.xpath("/html/body/ul/li/a/@href") print(result) result = tree.xpath("/html/body/ul/li") for li in result: print(li.xpath("./a/@href")) # 局部解析 result = tree.xpath("//div[@class='job']/text()") # [@class='xxx']属性选取 text()获取⽂本 print(result)
pyquery是⼀个相对新颖的数据解析⽅式. 有别于xpath和bs4. 它是使⽤css选择器作为语法规则的⼀种解析⽅式, 其⽤法⼏乎和前端的jQuery库⼀致.
pip install pyquery
# 使⽤pyquery加载html代码. 此时⾃动⽣成PyQuery对象 # 导⼊pyquery from pyquery import PyQuery as pq html = '<li><a href="http://www.baidu.com">百度</a></li>' # 加载HTML代码, 此时会⾃动⽣成PyQuery对象 query = pq(html) print(query) # <li><a href="http://www.baidu.com">百度</a></li> print(type(query)) # <class'pyquery.pyquery.PyQuery'> # 从PyQuery对象中提取内容 # 1. 标签选择器 li = query("li") print(li) # li标签 # 2. id选择器 a = query("#god") print(a) # 3. 类选择器 btn = query(".btn") print(btn) # 注意, 通过pyquery选择器提取的节点, 依然是pyquery对象. 所以. 就有了这种写法 # 4. 链式提取 btn = query("li")("a") # 先提取li, 然后再提取a. print(btn) # 但这种写法个⼈极不推荐. 看着很不舒服. 舒服的写法⼀定是这样的 # 5. 后代选择器 btn = query("li a") # 直接使⽤css选择器搞就完了. print(btn) # 提取⼀些重要属性试试看 # 6. 属性提取 btn = query("a") print(btn.attr("href")) # 提取href属性. attr()的作⽤就提取属性 print(btn.text()) # 提取a标签的⽂本信息 print(btn.html()) # 提取a标签中的html信息
query = PyQuery(html)
# 插播⼀条根据属性提取数据
# feiji = query("a[@href='feiji']")
# print(feiji)
# 拿到所有的a标签
lis = query("li a")
a_list = lis.items() # 批量数据处理必须加上items()
for a in a_list:
print(a.text())
from pyquery import PyQuery as pq
html = """
<HTML>
<div class="aaa">哒哒哒</div>
<div class="bbb">嘟嘟嘟</div>
</HTML>
"""
doc = pq(html)
doc(".aaa").after("""<div class="ccc">妈呀</div>""") # 插⼊HTML代码⽚段
doc(".bbb").append("<span>我爱span</span>") # 向HTML内层标签中插⼊HTML⽚段
doc(".aaa").html("<span>我是span</span>") # 修改标签内的html代码
doc('.ccc').text("美滋滋") # 修改⽂本内容doc(".ccc").attr("cs", "测试") # 添加属性
doc(".ccc").remove_attr("cs") # 删除属性print(doc)
文档
https://pyquery.readthedocs.io/en/latest/api.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。