源:參加阿里雲的Python 爬蟲實戰課。
本文代碼相關資源見本人CSDN主頁 ”正則表達式基礎.zip“。資源包括:
序
本文是課程 “Python網絡爬蟲快速入門到精通“ 的聽課筆記 + 自己跟隨的操作實戰。
正則表達式
概念
基礎1
- 全局匹配函數使用格式
re.compile(正則表達式).findall(源字符串)
普通字符 正常匹配
\n 匹配換行符
\t 匹配製表符
\w 匹配字母、數字、下劃線
\W 匹配除字母、數字下劃線
\d 匹配十進制數字
\D 匹配除十進制數字
\s 匹配空白字符
\S 匹配除空白字符
[ab89x] 原子表,匹配ab89x 中的任意一個
[^ab89x] 原子表,匹配除ab89x 中的任意一個字符
例子見同名 .py文件
基礎2
. 匹配除換行外任意一個字符
^ 匹配開始位置[在原子表代表非,不在代表匹配開始位置]
$ 匹配結束位置
* 前一個字符出現0\1\多次
? 前一個字符出現0\1次
+ 前一個字符出現1\多次
{n} 前一個字符恰好出現n次
{n,} 前一個字符至少n次。
{n,m} 前一個字符至少n,至多m次
| 模式選擇符或
() 模式單元,通俗說就是,想提取出什麼內容,就在正則中用小括號將其括起來。
基礎3
貪婪模式:儘可能多地匹配
懶惰模式:儘可能少地匹配,精準模式
默認貪婪模式
如果出現如下組合,則代表爲懶惰模式
*?
+?
基礎4
模式修正符:在不改變正則表達式的情況下通過模式修正符使匹配結果發生更改
re.S 讓.也可以匹配多行
re.I 讓匹配時忽略大小寫
Python 代碼測試
對應上面四個基礎的測試代碼如下:
import re
print("-"*50, "基礎1", "-"*50)
src = "aliyunedu"
pat = re.compile("yu").findall(src)
print(pat)
src ="'aliyunedu'"
pat = re.compile("yun\n").findall(src)
print(pat)
src ='"aliyun\nedu"'
pat = re.compile("yun\n").findall(src)
print(pat)
src ="aliyun89787nedu"
pat = re.compile("\w\d\w\d\d\w").findall(src)
print(pat)
# 原子表
pat = re.compile("\w\d[nedu]\w").findall(src)
print(pat)
"""
-------------------------------------------------- 基礎1 --------------------------------------------------
['yu']
[]
['yun\n']
['n89787']
['87ne']
"""
# 基礎2
print("-"*50, "基礎2", "-"*50)
src ="aliyunnnnji87362387aoyubaidu"
pat = re.compile("ali...").findall(src)
print(pat)
pat = re.compile("^ali...").findall(src)
print(pat)
pat = re.compile("bai..$").findall(src) # 注意,結束位置$ 是 \n
print(pat)
pat = re.compile("ali.*").findall(src) # TIPS:默認貪婪,即默認儘可能多地進行匹配
print(pat)
pat = re.compile("aliyun+").findall(src) # 多次n全部匹配出來
print(pat)
pat = re.compile("aliyun?").findall(src) # 匹配1次最多
print(pat)
pat = re.compile("yun{1,2}").findall(src) # 不超過2次,最少一次。
print(pat)
pat = re.compile("^al(i..)").findall(src) # 相匹配括號裏面的
print(pat)
# 基礎3
print("-"*50, "基礎3", "-"*50)
src ="poythonyhjskjsa"
pat = re.compile("p.*y").findall(src) # 儘可能多地匹配
print(pat)
pat = re.compile("p.*?y").findall(src) # 儘可能少地匹配
print(pat)
pat = re.compile("p.+?y").findall(src) # 儘可能少地匹配
print(pat)
src ="poythponyhjskjsa"
pat = re.compile("p.*y").findall(src) # 儘可能多地匹配
print(pat)
pat = re.compile("p.*?y").findall(src) # 儘可能少地匹配
print(pat)
pat = re.compile("p.+?y").findall(src) # 儘可能少地匹配
print(pat)
# 基礎4
print("-"*50, "基礎4", "-"*50)
src ="Python"
pat = re.compile("pyt").findall(src) # 匹配不到,因爲有大寫
print(pat)
pat = re.compile("pyt", re.I).findall(src) # 可以匹配大小寫
print(pat)
src ="我是阿里雲大學\n歡迎來學習Python網絡爬蟲課程"
pat = re.compile("阿里.*?Python").findall(src) # 匹配不到,因爲有換行
print(pat)
pat = re.compile("阿里.*?Python", re.S).findall(src) # 可以匹配換行
print(pat)
XPath表達式
概念
/ 逐層提取
text() 提取標籤下面的文本
//標籤名** 提取所有名爲**的標籤
//標籤名[@屬性=‘屬性值’] 提取屬性爲XX的標籤
@屬性名 代表取某個屬性值
<!DOCTYPE html>
<html>
<head>
<title>主頁</title>
</head>
<body>
<p>abc</p>
<p>bbbvb</p>
<a href="//qd.alibaba.com/go/v/pcdetail" target="_top">安全推薦</a>
<a href="//qd.alibaba.com/go/v/pcdetail" target="_top">安全推薦2</a>
<div class="J_AsyncDC" data-type="dr">
<div id="official-remind">明月幾時有</div>
</div>
</body>
</html>
分析以下XPath 表達式提取的內容:
提取標題=主頁
/html/head/title/text()
提取所有的div標籤
//div
提取div中
//div[@class=“tools”]
提取p標籤下的所有文本=[abc, bbbvb]
//p/text()
提取所有的a標籤
//a
提取所有的div標籤,且標籤屬性的id有定位=明月幾時有
//div[@id=“official-remind”]/text()
提取所有a標籤下的href屬性值=上面代碼的兩個網址
//a/@href
Python 代碼測試
from lxml import etree
print("-"*50, "測試: 打印 html 應該顯示內容", "-"*50)
html = etree.parse('XPath_test.html')
html_data = html.xpath('//*') # 打印是一個列表需要遍歷
print(html_data)
print("-"*50)
for i in html_data:
print(i.text)
print("-"*50, "測試: 打印 html 所有文本內容", "-"*50)
html = etree.parse('XPath_test.html')
html_data = etree.tostring(html, pretty_print=True)
res = html_data.decode('utf-8')
print(res)
print("-"*50, "測試: XPath表達式測試=標題提取", "-"*50)
html = etree.parse('XPath_test.html')
html_data = html.xpath('/html/head/title/text()')
for i in html_data:
print(i)
print("-"*50, "測試: XPath表達式測試=所有div標籤內容提取", "-"*50)
html_data = html.xpath('//div')
for i in html_data:
print(i)
print("-"*50, "測試: XPath表達式測試=所有div標籤指定屬性的內容提取", "-"*50)
html_data = html.xpath('//div[@id="official-remind"]/text()')
for i in html_data:
print(i)
print("-"*50, "測試: XPath表達式測試=所有p標籤內容提取", "-"*50)
html_data = html.xpath('//p/text() ')
for i in html_data:
print(i)
print("-"*50, "測試: XPath表達式測試=所有a標籤內容提取", "-"*50)
html_data = html.xpath('//a')
for i in html_data:
print(i)
print("-"*50, "測試: XPath表達式測試=所有a標籤href屬性的內容提取", "-"*50)
html_data = html.xpath('//a/@href')
for i in html_data:
print(i)
後注
來找自己瀏覽器的Headers屬性。
–(1)打開任意網頁,按F12,並選擇網絡(network)
–(2)任意點擊網頁連接,使其發生動作。點擊,觸發一個動作,User-Agent字樣的一串信息即是。