當(dāng)前位置:首頁(yè) > IT技術(shù) > 編程語(yǔ)言 > 正文

Python爬蟲小白教程(三)——使用正則表達(dá)式分析網(wǎng)頁(yè)
2021-12-01 22:55:44

正則表達(dá)式

正則表達(dá)式是對(duì)字符串操作的邏輯公式,在某些情況下通過使用正則表達(dá)式我們可以輕易地獲取到我們想要的結(jié)果,下面先學(xué)習(xí)簡(jiǎn)單的正則表達(dá)式后就開始實(shí)戰(zhàn)練習(xí)。

模式 概述 模式 概述
. 匹配任意字符,除了換行符 s 匹配空白字符
* 匹配前一個(gè)字符 0 次或多次 S 匹配任何非空白字符
+ 匹配前一個(gè)字符 1 次或多次 d 匹配數(shù)字,等價(jià)于 [0-9]
? 匹配前一個(gè)字符 0 次或 1 次 D 匹配任何非數(shù)字
^ 匹配字符串開頭 匹配一個(gè)換行符
$ 匹配字符串末尾 w 匹配字母數(shù)字
() 對(duì)正則表達(dá)式分組并記住匹配的文本 W 匹配非字母數(shù)字
[…] 表示一組字符。例:[amk] 匹配 ‘a(chǎn)’,‘m’或’k’ [^…] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。

以上只是一些基本的正則表達(dá)式,想更深入了解可以百度。

基本方法

re.match 方法

re.match嘗試從字符串的起始位置匹配一個(gè)模式,如果不是起始位置匹配成功的話,match()就返回none。
函數(shù)用法為:

re.match(pattern, string, flags=0)
參數(shù) 描述
pattern 匹配的正則表達(dá)式
string 匹配的字符串
flags 標(biāo)志位,用于控制正則表達(dá)式的匹配方式,如:是否區(qū)分大小寫,多行匹配等等。

flags的選擇如下

修飾符 描述
re.I 使匹配對(duì)大小寫不敏感
re.L 做本地化識(shí)別(locale-aware)匹配
re.M 多行匹配,影響 ^ 和 $
re.S 使 . 匹配包括換行在內(nèi)的所有字符
re.U 根據(jù)Unicode字符集解析字符。這個(gè)標(biāo)志影響 w, W, , B.
re.X 該標(biāo)志通過給予你更靈活的格式以便你將正則表達(dá)式寫得更易于理解。

舉個(gè)例子:

import re

string = 'Big bilibili is a learning website haha'
r = re.match(r'(.*) is (.*?) website', string)
print("匹配的整句話:", r.group(0))
print("匹配的第一個(gè)結(jié)果:", r.group(1))
print("匹配的第二個(gè)結(jié)果:", r.group(2))
print("匹配的結(jié)果列表:", r.groups())

得到的結(jié)果如下:

匹配的整句話: Big bilibili is a learning website
匹配的第一個(gè)結(jié)果: Big bilibili
匹配的第二個(gè)結(jié)果: a learning
匹配的結(jié)果列表: (‘Big bilibili’, ‘a(chǎn) learning’)

為什么要在正則表達(dá)式前加上r呢?
r'(.*) is (.*?) website'前面的r意思是raw string,代表純粹的字符串,這樣就不會(huì)對(duì)引號(hào)里面的反斜杠進(jìn)行特殊處理。因?yàn)樵谡齽t表達(dá)式中有一些類似于d的模式,所以模式中的單個(gè)反斜杠都要進(jìn)行轉(zhuǎn)譯。

re.search 方法

re.search 掃描整個(gè)字符串并返回第一個(gè)成功的匹配。
函數(shù)用法為:

re.search(pattern, string, flags=0)

它和re.match方法有什么區(qū)別呢?
re.match嘗試從字符串的起始位置匹配一個(gè)模式,而re.search 掃描整個(gè)字符串并返回第一個(gè)成功的匹配。舉個(gè)簡(jiǎn)單的例子:

import re

string = 'Big 6 bilibili is a learning website haha'
r = re.search(r'd (.*) is (.*?) website', string)
print("匹配的整句話:", r.group(0))
print("匹配的第一個(gè)結(jié)果:", r.group(1))
print("匹配的第二個(gè)結(jié)果:", r.group(2))
print("匹配的結(jié)果列表:", r.groups())

使用re.search得到結(jié)果如下:

匹配的整句話: 6 bilibili is a learning website
匹配的第一個(gè)結(jié)果: bilibili
匹配的第二個(gè)結(jié)果: a learning
匹配的結(jié)果列表: (‘bilibili’, ‘a(chǎn) learning’)

使用re.match方法

import re

string = 'Big 6 bilibili is a learning website haha'
r = re.match(r'd (.*) is (.*?) website', string)
print(r)

因?yàn)樽址_頭不是數(shù)字,故無法匹配,得到結(jié)果為None。
因此我個(gè)人認(rèn)為match方法用到的地方可能會(huì)比較少。

re.findall 方法

在字符串中找到正則表達(dá)式所匹配的所有子串,并返回一個(gè)列表,如果沒有找到匹配的,則返回空列表。
舉個(gè)例子和上面兩種方法做個(gè)比較:

import re

r_match = re.match(r'd+', '1234 is the first number, 6666 is the second.')
r_search = re.search(r'd+', 'The first number is 1234, the second number is 6666.')
r_findall = re.findall(r'd+', 'The first number is 1234, the second number is 6666.')

print("r_match:", r_match.group())
print("r_search:", r_search.group())
print("r_findall:", r_findall)

得到的結(jié)果如下:

r_match: 1234
r_search: 1234
r_findall: [‘1234’, ‘6666’]

獲取自己的IP地址

下面我們通過查看自己IP的網(wǎng)站來看一下使用正則表達(dá)式的優(yōu)越性。
我們使用 http://httpbin.org/get 來查看自己的IP地址。
首先分析網(wǎng)頁(yè)。
Python爬蟲小白教程(三)——使用正則表達(dá)式分析網(wǎng)頁(yè)_正則表達(dá)式
打碼處為我的電腦現(xiàn)在的IP地址。通過分析網(wǎng)頁(yè)可知IP地址在一堆字符中的某一處,這樣使用以前的方法一層一層分析已經(jīng)不行了,所以我們現(xiàn)在使用正則表達(dá)式來獲取一下IP地址。
我們定義一下獲取頁(yè)面的函數(shù)。

def get_page(url,params=None,headers=None,proxies=None):

    response = requests.get(url, headers=headers, params=params, proxies=proxies)
    print("解析網(wǎng)址:",response.url)
    page = BeautifulSoup(response.text, 'lxml')
    print("響應(yīng)狀態(tài)碼:", response.status_code)
    
    return page

然后就可以獲取頁(yè)面的源碼了:

url = 'http://httpbin.org/get'
headers = {
    'Host': 'httpbin.org',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'
    }

page = get_page(url, headers=headers)

使用

page.text

來看一下結(jié)果(打碼處為IP地址):
Python爬蟲小白教程(三)——使用正則表達(dá)式分析網(wǎng)頁(yè)_大數(shù)據(jù)_02
然后我們分析一下IP地址的特點(diǎn):
IP地址為由.分隔開的四組數(shù)字組成,每組數(shù)字有1-3位數(shù)字,這樣我們便可以定義IP地址的正則表達(dá)式r'd{1,3}.d{1,3}.d{1,3}.d{1,3}',其中.匹配字符串中的.。因此可得獲得IP地址的代碼如下:

ip = re.findall(r'd{1,3}.d{1,3}.d{1,3}.d{1,3}', page.text)
print(ip[0])

這樣便可以得到本機(jī)的IP地址了。

爬蟲系列

Python爬蟲小白教程(一)—— 靜態(tài)網(wǎng)頁(yè)抓取
Python爬蟲小白教程(二)—— 爬取豆瓣評(píng)分TOP250電影
Python爬蟲小白教程(三)——使用正則表達(dá)式分析網(wǎng)頁(yè)
Python爬蟲小白教程(四)—— 反反爬之IP代理池
Python爬蟲小白教程(五)—— 多線程爬蟲

本文摘自 :https://blog.51cto.com/u

開通會(huì)員,享受整站包年服務(wù)立即開通 >