正則表達(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é)果如下:
獲取自己的IP地址r_match: 1234
r_search: 1234
r_findall: [‘1234’, ‘6666’]
下面我們通過查看自己IP的網(wǎng)站來看一下使用正則表達(dá)式的優(yōu)越性。
我們使用 http://httpbin.org/get 來查看自己的IP地址。
首先分析網(wǎng)頁(yè)。
打碼處為我的電腦現(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地址):
然后我們分析一下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