Pyhton爬蟲知識之正則表達(dá)式詳解
前言
在爬蟲的開發(fā)中,需要把有用的信息從一大段文本中提取出來,正則表達(dá)式是提取信息的方法之一。
1、正則表達(dá)式基礎(chǔ)
正則表達(dá)式(Regular Expression)是一段字符串,它可以表示一段有規(guī)律的信息。Python自帶一個(gè)正則表達(dá)式模塊 - re,通過這個(gè)模塊可以查找、提取、替換一段有規(guī)律的信息。在程序開發(fā)中,要讓計(jì)算機(jī)程序從一大段文本中找到需要的內(nèi)容,就可以使用正則表達(dá)式來實(shí)現(xiàn)。
使用正則表達(dá)式有如下步驟:
(1)尋找規(guī)律
(2)使用正則符號表示規(guī)律
(3)提取信息
2、正則表達(dá)式的基本符號
2.1 點(diǎn)號 “.”
一個(gè)點(diǎn)號可以代替除了換行符以外的任何一個(gè)字符,包括但不限于英文字母、數(shù)字、漢字、英文標(biāo)點(diǎn)符號和中文標(biāo)點(diǎn)符號。
2.2 星號 “*”
一個(gè)星號可以表示它前面的一個(gè)子表達(dá)式(普通字符、另一個(gè)或幾個(gè)正則表達(dá)式符號)0次到無限次。
2.3 問號 “?”
一個(gè)問號可以表示它前面的子表達(dá)式0次或者1次。注意,這里的問號是英文問號。
2.4 反斜杠 “\”
反斜杠在正則表達(dá)式里面不能單獨(dú)使用,甚至在整個(gè) Python 里都不能單獨(dú)使用。反斜杠需要和其他的字符配合使用來把特殊符號變成普通符號,把普通符號變成特殊符號:
2.5 數(shù)字 “\d”
正則表達(dá)式里面使用 “\d” 來表示一位數(shù)字。為什么要用字母d呢?因?yàn)閐是英文“digital(數(shù)字)”的首字母。強(qiáng)調(diào)一下,“\d”雖然是由反斜杠和字母d構(gòu)成的,但是要把“\d”看成一個(gè)正則表達(dá)式符號整體。
2.6 小括號 “()”
小括號可以把括號里面的內(nèi)容提取出來。
3、Python中使用正則表達(dá)式
Python 已經(jīng)自帶了一個(gè)功能非常強(qiáng)大的正則表達(dá)式模塊。使用這個(gè)模塊可以非常方便地通過正則表達(dá)式來從一大段文字中提取有規(guī)律的信息。Python的正則表達(dá)式模塊名字為“re”,也就是“regularexpression”的首字母縮寫。在Python中需要首先導(dǎo)入這個(gè)模塊再進(jìn)行使用。導(dǎo)入的語句為:
import re # pycharm 如果報(bào)錯(cuò) Alt+Enter 自動(dòng)導(dǎo)入即可
下面我們來介紹一下常用的API:
3.1 findall
Python的正則表達(dá)式模塊包含一個(gè)findall方法,它能夠以列表的形式返回所有滿足要求的字符串。
def findall(pattern, string, flags=0): """Return a list of all non-overlapping matches in the string. If one or more capturing groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result.""" return _compile(pattern, flags).findall(string)
pattern表示正則表達(dá)式,string表示原來的字符串,flags表示一些特殊功能的標(biāo)志。
findall 的結(jié)果是一個(gè)列表,包含了所有的匹配到的結(jié)果。如果沒有匹配到結(jié)果,就會返回空列表:
content = '我的電腦密碼是:123456,我的手機(jī)密碼是:888888,我的家門密碼是:000000,勿忘!' pwd_list = re.findall('是:(.*?),', content) machine_list = re.findall('我的(.*?)密碼是:', content) name_list = re.findall('名字是(.*?),', content) print('所有密碼為:{}'.format(pwd_list)) print('所屬為:{}'.format(machine_list)) print('用戶姓名為:{}'.format(name_list))
結(jié)果中很明顯沒有匹配到結(jié)果的為空 List 。這里還有一個(gè)變化:在匹配密碼的時(shí)候,如左圖會少一個(gè)。原因就出在匹配上面,我的匹配規(guī)則為:'是:(.*?),',必須嚴(yán)格滿足這個(gè)格式的文本的中間密碼部分才能被提取出來,重點(diǎn)就是后面的 , ,如右圖加上了 ,勿忘! 就使得前面的文本滿足匹配規(guī)則,從而進(jìn)行提?。?/p>
當(dāng)需要提取某些內(nèi)容的時(shí)候,使用小括號將這些內(nèi)容括起來,這樣才不會得到不相干的信息。如果包含多個(gè) “(.*?)” 如下圖所示,返回的仍然是一個(gè)列表,但是列表里面的元素變?yōu)榱嗽M,元組里面的第1個(gè)元素是賬號,第2個(gè)元素為密碼:
函數(shù)原型中有一個(gè)flags參數(shù)。這個(gè)參數(shù)是可以省略的;當(dāng)不省略的時(shí)候,具有一些輔助功能,例如忽略大小寫、忽略換行符等。這里以忽略換行符為例來進(jìn)行說明:
常用的參數(shù):
re.I
IGNORECASE
忽略字母大小寫re.L
LOCALE
影響 “w, “W, “b, 和 “B,這取決于當(dāng)前的本地化設(shè)置。re.M
MULTILINE
使用本標(biāo)志后,‘^’和‘$’匹配行首和行尾時(shí),會增加換行符之前和之后的位置。re.S
DOTALL
使 “.” 特殊字符完全匹配任何字符,包括換行;沒有這個(gè)標(biāo)志, “.” 匹配除了換行符外的任何字符。re.X
VERBOSE
當(dāng)該標(biāo)志被指定時(shí),在 RE 字符串中的空白符被忽略,除非該空白符在字符類中或在反斜杠之后。
它也可以允許你將注釋寫入 RE,這些注釋會被引擎忽略;
注釋用 “#”號 來標(biāo)識,不過該符號不能在字符串或反斜杠之后。
參考:Python 正則表達(dá)式 flags 參數(shù)
3.2 serach
search() 的用法和 findall() 的用法一樣,但是 search() 只會返回第1個(gè)滿足要求的字符串。一旦找到符合要求的內(nèi)容,它就會停止查找。對于從超級大的文本里面只找第1個(gè)數(shù)據(jù)特別有用,可以大大提高程序的運(yùn)行效率。
def search(pattern, string, flags=0): """Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found.""" return _compile(pattern, flags).search(string)
對于結(jié)果,如果匹配成功,則是一個(gè)正則表達(dá)式的對象,要得到匹配到的結(jié)果,則需要通過.group()這個(gè)方法來獲取里面的值;如果沒有匹配到任何數(shù)據(jù),就是 None:
只有在.group()里面的參數(shù)為1的時(shí)候,才會把正則表達(dá)式里面的括號中的結(jié)果打印出來。
.group()的參數(shù)最大不能超過正則表達(dá)式里面括號的個(gè)數(shù)。參數(shù)為1表示讀取第1個(gè)括號中的內(nèi)容,參數(shù)為2表示讀取第2個(gè)括號中的內(nèi)容,以此類推:
3.3 “.* ” 和 “.*?” 的區(qū)別
在爬蟲開發(fā)中,.*? 這3個(gè)符號大多數(shù)情況下一起使用。
- 點(diǎn)號表示任意非換行符的字符,星號表示匹配它前面的字符0次或者任意多次。所以“.*”表示匹配一串任意長度的字符串任意次。
- 這個(gè)時(shí)候必須在“.*”的前后加其他的符號來限定范圍,否則得到的結(jié)果就是原來的整個(gè)字符串。
- 如果在“.*”的后面加一個(gè)問號,變成 “.*?”,那么可以得到什么樣的結(jié)果呢?問號表示匹配它前面的符號0次或者1次。于是 “.*?” 的意思就是匹配一個(gè)能滿足要求的最短字符串。
使用“(.*)”得到的是只有一個(gè)元素的列表,里面是一個(gè)很長的字符串。
使用“(.*?)”得到的結(jié)果是包含3個(gè)元素的列表,每個(gè)元素直接對應(yīng)原來文本中的每個(gè)密碼。
總結(jié):
①“.*”:貪婪模式,獲取最長的滿足條件的字符串。②“.*?”:非貪婪模式,獲取最短的能滿足條件的字符串。
4、正則表達(dá)式提取技巧
4.1 不需使用 compile
def findall(pattern, string, flags=0): """Return a list of all non-overlapping matches in the string. If one or more capturing groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result.""" return _compile(pattern, flags).findall(string) def compile(pattern, flags=0): "Compile a regular expression pattern, returning a Pattern object." return _compile(pattern, flags)
使用re.compile()的時(shí)候,程序內(nèi)部調(diào)用的是_compile()方法;當(dāng)使用re.finall()的時(shí)候,在模塊內(nèi)部自動(dòng)先調(diào)用了_compile()方法,再調(diào)用findall()方法。re.findall()自帶re.compile()的功能,所以沒有必要使用re.compile()。
4.2 先抓大再抓小
一些無效內(nèi)容和有效內(nèi)容可能具有相同的規(guī)則。這種情況下很容易把有效內(nèi)容和無效內(nèi)容混在一起,如下面這段文字:
有效用戶:姓名: 張三姓名: 李四姓名: 王五無效用戶:姓名: 不知名的小蝦米姓名: 隱身的張大俠
有效用戶和無效用戶的名字前面都以“姓名: ”開頭,如果使用“姓名: (.*?)\n”來進(jìn)行匹配,就會把有效信息和無效信息混在一起,難以區(qū)分:
要解決這個(gè)問題,就需要使用先抓大再抓小的技巧。先把有效用戶這個(gè)整體匹配出來,再從有效用戶里面匹配出人名:
4.3 括號內(nèi)和括號外
在上面的例子中,括號和“.*?”都是一起使用的,因此可能會有讀者認(rèn)為括號內(nèi)只能有這3種字符,不能有其他普通的字符。但實(shí)際上,括號內(nèi)也可以有其他字符,對匹配結(jié)果的影響結(jié)果如下:
其實(shí)不難理解,只需要記?。?quot;按照匹配規(guī)則查找,括號內(nèi)的被提取" 就可以了!
總結(jié)
到此這篇關(guān)于Pyhton爬蟲知識之正則表達(dá)式的文章就介紹到這了,更多相關(guān)Pyhton爬蟲正則表達(dá)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 零基礎(chǔ)寫python爬蟲之神器正則表達(dá)式
- Python的爬蟲包Beautiful Soup中用正則表達(dá)式來搜索
- python3爬蟲之入門基礎(chǔ)和正則表達(dá)式
- python爬蟲 正則表達(dá)式使用技巧及爬取個(gè)人博客的實(shí)例講解
- python爬蟲正則表達(dá)式之處理換行符
- 玩轉(zhuǎn)python爬蟲之正則表達(dá)式
- Python爬蟲正則表達(dá)式常用符號和方法
- Python爬蟲之正則表達(dá)式基本用法實(shí)例分析
- Python爬蟲教程之利用正則表達(dá)式匹配網(wǎng)頁內(nèi)容
- Python 爬蟲學(xué)習(xí)筆記之正則表達(dá)式
相關(guān)文章
Python實(shí)現(xiàn)去除圖片中指定顏色的像素功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)去除圖片中指定顏色的像素功能,結(jié)合具體實(shí)例形式分析了Python基于pil與cv2模塊的圖形載入、運(yùn)算、轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下2019-04-04快速解決Django關(guān)閉Debug模式無法加載media圖片與static靜態(tài)文件
這篇文章主要介紹了快速解決Django關(guān)閉Debug模式無法加載media圖片與static靜態(tài)文件的操作方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04Python使用multiprocessing如何實(shí)現(xiàn)多進(jìn)程
這篇文章主要介紹了Python使用multiprocessing如何實(shí)現(xiàn)多進(jìn)程問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02Python操作MongoDB的教程詳解(插,查,改,排,刪)
MongoDB是一個(gè)基于分布式文件存儲的數(shù)據(jù)庫。是一個(gè)介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的產(chǎn)品,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫的。本文將詳細(xì)和大家聊聊Python操作MongoDB的方法,需要的可以參考一下2022-09-09Python+OpenCV實(shí)戰(zhàn)之拖拽虛擬方塊的實(shí)現(xiàn)
這篇文章主要介紹了如何利用Python+OpenCV實(shí)現(xiàn)拖拽虛擬方塊的效果,即根據(jù)手指坐標(biāo)位置和矩形的坐標(biāo)位置,判斷手指點(diǎn)是否在矩形上,如果在則矩形跟隨手指移動(dòng),感興趣的可以了解一下2022-08-08Scrapy框架實(shí)現(xiàn)的登錄網(wǎng)站操作示例
這篇文章主要介紹了Scrapy框架實(shí)現(xiàn)的登錄網(wǎng)站操作,結(jié)合實(shí)例形式分析了Scrapy登錄網(wǎng)站cookies方式、post請求方式登錄網(wǎng)站相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2020-02-02初學(xué)python的操作難點(diǎn)總結(jié)(新手必看篇)
下面小編就為大家?guī)硪黄鯇W(xué)python的操作難點(diǎn)總結(jié)(新手必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08