欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python使用正則表達(dá)式實(shí)現(xiàn)爬蟲數(shù)據(jù)抽取

 更新時(shí)間:2020年08月17日 10:32:38   作者:Amo Xiang  
這篇文章主要介紹了Python使用正則表達(dá)式實(shí)現(xiàn)爬蟲數(shù)據(jù)抽取,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. 為什么要使用正則表達(dá)式?

首先,大家來看一個(gè)例子。一個(gè)文本文件里面存儲了一些市場職位信息,格式如下所示:

Python3 高級開發(fā)工程師 上?;ソ探逃萍加邢薰旧虾?浦東新區(qū)2萬/月02-18滿員
測試開發(fā)工程師(C++/python) 上海墨鹍數(shù)碼科技有限公司上海-浦東新區(qū)2.5萬/每月02-18未滿員
Python3 開發(fā)工程師 上海德拓信息技術(shù)股份有限公司上海-徐匯區(qū)1.3萬/每月02-18剩余11人
測試開發(fā)工程師(Python) 赫里普(上海)信息科技有限公司上海-浦東新區(qū)1.1萬/每月02-18剩余5人
Python高級開發(fā)工程師 上海行動(dòng)教育科技股份有限公司上海-閔行區(qū)2.8萬/月02-18剩余255人
python開發(fā)工程師 上海優(yōu)似騰軟件開發(fā)有限公司上海-浦東新區(qū)2.5萬/每月02-18滿員

現(xiàn)在,我們需要編寫一個(gè)程序,從這些文本里面抓取所有職位的薪資。獲取結(jié)果如下所示:

2
2.5
1.3
1.1
2.8
2.5

怎么做?大家可以先自己思考一下。這是典型的字符串處理。分析這里面的規(guī)律,可以發(fā)現(xiàn),薪資的數(shù)字后面都有關(guān)鍵字萬/月或者萬/每月。根據(jù)我們學(xué)過的知識,我們不難寫出下面的代碼:

html_str = """
 Python3 高級開發(fā)工程師 上海互教教育科技有限公司上海-浦東新區(qū)2萬/月02-18滿員
 測試開發(fā)工程師(C++/python) 上海墨鹍數(shù)碼科技有限公司上海-浦東新區(qū)2.5萬/每月02-18未滿員
 Python3 開發(fā)工程師 上海德拓信息技術(shù)股份有限公司上海-徐匯區(qū)1.3萬/每月02-18剩余11人
 測試開發(fā)工程師(Python) 赫里普(上海)信息科技有限公司上海-浦東新區(qū)1.1萬/每月02-18剩余5人
 Python高級開發(fā)工程師 上海行動(dòng)教育科技股份有限公司上海-閔行區(qū)2.8萬/月02-18剩余255人
 python開發(fā)工程師 上海優(yōu)似騰軟件開發(fā)有限公司上海-浦東新區(qū)2.5萬/每月02-18滿員
"""
# 將字符串html_str中每一行的數(shù)據(jù)提取出來存入到一個(gè)列表中
position_info_list = html_str.splitlines()
for position_info in position_info_list: # 遍歷
 if position_info: # 判斷是否有數(shù)據(jù)
  # 查找萬/月或者是萬/每月的索引
  idx = position_info.find("萬/月") if position_info.find("萬/月") != -1 else position_info.find("萬/每月")
  end_pos = idx # 記錄結(jié)束位置
  if idx == -1:
   continue # 上面兩種都沒找到
  find_start = idx - 1 # 記錄萬字前的位置
  while position_info[find_start].isdigit() or position_info[find_start] == ".":
   find_start -= 1
  start_pos = find_start + 1 # 開始位置
  print(position_info[start_pos: end_pos]) # 切片獲取薪資

運(yùn)行一下,發(fā)現(xiàn)完全可以。如圖所示:


在你高興完之后,我們再看看寫的代碼。怎么樣?太麻煩了,是不是。為了從每行獲取薪資對應(yīng)的數(shù)字,我們可是寫了不少行代碼。這種從字符串中搜索出某種特征的子串有沒有更簡單的方法呢?解決方案就是我們今天要介紹的正則表達(dá)式。如果我們使用正則表達(dá)式,代碼可以這樣:

import re

html_str = """
 Python3 高級開發(fā)工程師 上海互教教育科技有限公司上海-浦東新區(qū)2萬/月02-18滿員
 測試開發(fā)工程師(C++/python) 上海墨鹍數(shù)碼科技有限公司上海-浦東新區(qū)2.5萬/每月02-18未滿員
 Python3 開發(fā)工程師 上海德拓信息技術(shù)股份有限公司上海-徐匯區(qū)1.3萬/每月02-18剩余11人
 測試開發(fā)工程師(Python) 赫里普(上海)信息科技有限公司上海-浦東新區(qū)1.1萬/每月02-18剩余5人
 Python高級開發(fā)工程師 上海行動(dòng)教育科技股份有限公司上海-閔行區(qū)2.8萬/月02-18剩余255人
 python開發(fā)工程師 上海優(yōu)似騰軟件開發(fā)有限公司上海-浦東新區(qū)2.5萬/每月02-18滿員
"""
salary_list = re.findall(r"([\d.]+)萬/每?月", html_str)
for salary in salary_list:
 print(salary)

運(yùn)行一下看看,結(jié)果是一樣的。但是代碼卻簡單多了。從上面的例子可以看出,用正則表達(dá)式關(guān)鍵的地方在于如何寫出正確的表達(dá)式語法。正則表達(dá)式非常強(qiáng)大,語法非常復(fù)雜,如果你英文閱讀能力還可以,那太好了,點(diǎn)擊這里,參考Python官方文檔里面的描述 。具體的使用細(xì)節(jié)包括語法都在里面。本文會給大家介紹一些常見的正則表達(dá)式語法。

2. 什么是正則表達(dá)式?

在處理字符串時(shí),經(jīng)常會有查找符合某些復(fù)雜規(guī)則的字符串的需求。正則表達(dá)式就是用于描述這些規(guī)則的工具。換句話說,正則表達(dá)式就是記錄文本規(guī)則的代碼。對于接觸過DOS/終端的用戶來說,如果想匹配當(dāng)前文件夾下所有的文本文件,可以輸入dir *.txt/ls *.txt命令,按<Enter>鍵后,所有.txt文件將會被列出來。這里的*.txt即可理解為一個(gè)簡單的正則表達(dá)式。


數(shù)據(jù)庫中使用正則表達(dá)式,如圖所示:

3. re模塊操作

Python提供了re模塊,用于實(shí)現(xiàn)正則表達(dá)式的操作。在實(shí)現(xiàn)時(shí),可以使用re模塊提供的方法search()、 match()、findall()等進(jìn)行字符串處理,也可以先使用re模塊compile()方法將模式字符串轉(zhuǎn)換為正則表達(dá)式對象,然后再使用該正則表達(dá)式對象的相關(guān)方法來操作字符串。re模塊在使用時(shí),需要先應(yīng)用import語句引入,具體代碼如下:

import re

這里因?yàn)槲覀冞€沒有學(xué)習(xí)匹配的規(guī)則,所以先學(xué)習(xí)一下match方法,其他的方法在本文末尾講解。match()方法用于從字符串的開始處進(jìn)行匹配,如果在起始位置匹配成功,則返回Match對象,否則返回None,語法格式如下:

re.match(pattern, string, [flags] )
參數(shù)說明:
1. pattern:表示模式字符串,由要匹配的正則表達(dá)式轉(zhuǎn)換而來。
2. string:表示要匹配的字符串。
3. flags:可選參數(shù),表示標(biāo)志位,用于控制匹配方式,如是否區(qū)分字母大小寫。

常用的flags如下表所示:

標(biāo)志 說明
A 或ASCII 對于\w、\W、\b、\B、\d、\D、\s和\S只進(jìn)行ASCII匹配(僅適用于Python 3.x)
I或IGNORECASE 執(zhí)行不區(qū)分字母大小寫的匹配
M或MULTILINE 將^和$用于包括整個(gè)字符串的開始和結(jié)尾的每一行(默認(rèn)情況下,僅適用于整個(gè)字符串的開始和結(jié)尾處)
S或DOTALL 使用(.)字符匹配所有字符,包括換行符
X或VERBOSE 忽略模式字符串中未轉(zhuǎn)義的空格和注釋

例如,匹配字符串是否以amo_開頭,不區(qū)分字母大小寫,代碼如下:


從上面的執(zhí)行結(jié)果中可以看出,字符串Amo_cool是以amo_開頭,所以返回一個(gè)Match對象,而字符串外貌描述 Amo_ cool不是以amo_開頭,將返回None。這是因?yàn)?code>match()方法從字符串的開始位置開始匹配,當(dāng)第一個(gè)字母不符合條件時(shí),則不再進(jìn)行匹配,直接返回None。Match對象中包含了匹配值的位置和匹配數(shù)據(jù)。其中,要獲取匹配值的起始位置可以使用Match對象的start() 方法 要獲取匹配值的結(jié)束位置可以使用end()方法 通過span()方法可以返回匹配位置的元組 通過string屬性可以獲取要匹配的字符串。例如下面的代碼:

import re

pattern = r"amo_" # 模式字符串
str1 = "Amo_cool amo_cool" # 要匹配的字符串
match = re.match(pattern, str1, re.I) # 匹配字符串 不區(qū)分大小寫
print(f"匹配值的起始位置: {match.start()}")
print(f"匹配值的結(jié)束位置: {match.end()}")
print(f"匹配位置的元組: {match.span()}")
print(f"要匹配的字符串: {match.string}")
print(f"匹配數(shù)據(jù): {match.group()}"

運(yùn)行結(jié)果如圖所示:


Python中字符串前面加上r表示原生字符串,與大多數(shù)編程語言相同,正則表達(dá)式里使用\作為轉(zhuǎn)義字符,這就可能造成反斜杠困擾。假如你需要匹配文本中的字符\,那么使用編程語言表示的正則表達(dá)式里將需要4個(gè)反斜杠\:前兩個(gè)和后兩個(gè)分別用于在編程語言里轉(zhuǎn)義成反斜杠,轉(zhuǎn)換成兩個(gè)反斜杠后再在正則表達(dá)式里轉(zhuǎn)義成一個(gè)反斜杠。Python里的原生字符串很好地解決了這個(gè)問題,有了原生字符串,你再也不用擔(dān)心是不是漏寫了反斜杠,寫出來的表達(dá)式也更直觀。如圖所示:

4. 匹配單個(gè)字符

在上一小節(jié)中,了解到通過re模塊能夠完成使用正則表達(dá)式來匹配字符串。本小節(jié),將要講解正則表達(dá)式的單字符匹配,具體的規(guī)則,如下所示:

實(shí)例 描述
. 匹配除"\n"之外的任何單個(gè)字符。要匹配包括"\n"在內(nèi)的任何字符,請使用"[.\n]"模式。
\d 匹配一個(gè)數(shù)字字符。等價(jià)于 [0-9]。
\D 匹配一個(gè)非數(shù)字字符。等價(jià)于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、換頁符等等。等價(jià)于[ \f\n\r\t\v]。
\S 匹配任何非空白字符。等價(jià)于 [^ \f\n\r\t\v]。
\w 匹配包括下劃線的任何單詞字符。等價(jià)于"[A-Za-z0-9_]"。
\W 匹配任何非單詞字符。等價(jià)于"[^A-Za-z0-9_]"。
[…] 用來表示一組字符,單獨(dú)列出:[amk] 匹配 ‘a(chǎn)',‘m'或'k'
[^…] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
^ 匹配字符串的開頭
$ 匹配字符串的結(jié)尾

例子如下:

5. 匹配多個(gè)字符

匹配多個(gè)字符的相關(guān)格式:

實(shí)例 描述
re* 匹配0個(gè)或多個(gè)的表達(dá)式 。
re+ 匹配1個(gè)或多個(gè)的表達(dá)式。
re? 匹配0個(gè)或1個(gè)由前面的正則表達(dá)式定義的片段,非貪婪方式。
re{n} 匹配n個(gè)前面表達(dá)式。例如,o{2}不能匹配Bob中的o,但是能匹配food中的兩個(gè)o。
re{n,} 精確匹配n個(gè)前面表達(dá)式。例如,o{2,}不能匹配Bob中的o,但能匹配foooood中的所有o。o{1,}等價(jià)于o+。o{0,}則等價(jià)于o*。
re{n,m} 匹配 n 到 m 次由前面的正則表達(dá)式定義的片段,貪婪方式

例子如下:

6. 匹配分組

實(shí)例 描述
a|b 匹配a或b
(re) 匹配括號內(nèi)的表達(dá)式,也表示一個(gè)組
\num 引用分組num匹配到的字符串
(?P<name>) 分組起別名
(?P=name) 引用別名為name分組匹配到的字符串

練習(xí)1:匹配出0-100之間的數(shù)字

result = re.match(r"[1-9]?\d$|100", "70").group()

練習(xí)2:匹配出163、126、qq、sina郵箱
要求:可使用英文小寫 數(shù)字 下劃線下劃線不能在首尾且@符號之前有4到16位字符

result = re.match(r"^[a-z0-9][a-z0-9_]{2,14}[a-z0-9]@(163|126|qq|sina)\.com$", "test@sina.com").group()

練習(xí)3:匹配出<html><body>amo666</body></html>

import re

str1 = "<html><body>amo666</body></html>"
pattern1 = r"<([a-zA-Z]*)><([a-zA-Z]*)>.*</\2></\1>"
match_obj1 = re.match(pattern1, str1)
print(match_obj1.group())
pattern2 = r"<(?P<name1>[a-zA-Z]*)><(?P<name2>[a-zA-Z]*)>.*</(?P=name2)></(?P=name1)>"
match_obj2 = re.match(pattern2, str1)
print(match_obj2.group())

執(zhí)行結(jié)果如下:

 <html><body>amo666</body></html>
<html><body>amo666</body></html>

7. re模塊的高級用法

7.1 使用search()方法進(jìn)行匹配

search()方法用于在整個(gè)字符串中搜索第一個(gè)匹配的值, 如果匹配成功,則返回Match對象,否則返回None,語法格式如下:

re. search(pattern, string, [flags])

參數(shù)說明:

  1. pattern:表示模式字符串,由要匹配的正則表達(dá)式轉(zhuǎn)換而來。
  2. string:表示要匹配的字符串。
  3. flags:可選參數(shù),表示標(biāo)志位,用于控制匹配方式,如是否區(qū)分字母大小寫。

例如,搜索第一個(gè)以amo_開頭的字符串,不區(qū)分字母大小寫,代碼如下:

import re

match_obj1 = re.search(r"amo_\w+", "Amo_SHOP amo_shop", re.I)
print(match_obj1)
match_obj2 = re.search(r"amo_\w+", "項(xiàng)目名稱Amo_SHOP amo_shop", re.I)
print(match_obj2)

執(zhí)行結(jié)果如下:


從上面的運(yùn)行結(jié)果中可以看出,search()方法不僅僅是在字符串的起始位置搜索,其他位置有符合的匹配也可以。

7.2 使用findall()方法進(jìn)行匹配

findall()方法用于在整個(gè)字符串中搜索所有符合正則表達(dá)式的字符串,并以列表的形式返回。如果匹配成功,則返回包含匹配結(jié)構(gòu)的列表,否則返回空列表。其語法格式如下:

re. findall(pattern, string, [flags])

參數(shù)說明:

  • pattern:表示模式字符串,由要匹配的正則表達(dá)式轉(zhuǎn)換而來。
  • string:表示要匹配的字符串。
  • flags:可選參數(shù),表示標(biāo)志位,用于控制匹配方式,如是否區(qū)分字母大小寫。

例如,搜索以amo_開頭的字符串,不區(qū)分字母大小寫,代碼如下:

import re

result1 = re.findall(r"amo_\w+", "Amo_SHOP amo_shop", re.I)
print(result1)
result2 = re.findall(r"amo_\w+", "項(xiàng)目名稱Amo_SHOP amo_shop")
print(result2)

執(zhí)行結(jié)果如下:


如果在指定的模式字符串中,包含分組,則返回與分組匹配的文本列表。例如:

import re

result1 = re.findall(r"[1-9]{1,3}(\.[0-9]{1,3}){3}", "127.0.0.1 192.168.31.157")
print(result1)

上面的代碼的執(zhí)行結(jié)果如下:

['.1', '.157']

從上面的結(jié)果中可以看出,并沒有得到匹配的IP地址,這是因?yàn)樵谀J阶址谐霈F(xiàn)了分組,所以得到的結(jié)果是根據(jù)分組進(jìn)行匹配的結(jié)果,即(\.[0一9]{1,3})匹配的結(jié)果。如果想獲取整個(gè)模式字符串的匹配,可以將整個(gè)模式字符串使用一對小括號進(jìn)行分組,然后在獲取結(jié)果時(shí),只取返回值列表的每個(gè)元素(是一個(gè)元組)的第1個(gè)元素。代碼如下:

import re

str1 = "127.0.0.1 192.168.31.157"
result1 = re.findall(r"([1-9]{1,3}(\.[0-9]{1,3}){3})", str1)
for item in result1:
 print(item[0])

執(zhí)行結(jié)果如下:

127.0.0.1
192.168.31.157

7.3 替換字符串

sub()方法用于實(shí)現(xiàn)字符串替換,語法格式如下:

re. sub( pattern, repl, string, count, flags)

參數(shù)說明:

  • pattern:表示模式字符串,由要匹配的正則表達(dá)式轉(zhuǎn)換而來。
  • repl: 表示替換的字符串。
  • string:表示要被查找替換的原始字符串。
  • count:可選參數(shù),表示模式匹配后替換的最大次數(shù),默認(rèn)值為0,表示替換所有的匹配。
  • flags:可選參數(shù),表示標(biāo)志位,用于控制匹配方式,如是否區(qū)分字母大小寫。

例如,隱藏中獎(jiǎng)信息中的手機(jī)號碼,代碼如下:

import re

pattern = r"1[34578]\d{9}"
str1 = "中獎(jiǎng)號碼為: 84978981 聯(lián)系電話為: 13611111111"
result = re.sub(pattern, "1XXXXXXXXXX", str1)
print(result)

執(zhí)行結(jié)果如下:

中獎(jiǎng)號碼為: 84978981 聯(lián)系電話為: 1XXXXXXXXXX

7.4 使用正則表達(dá)式分割字符串

split()方法用于實(shí)現(xiàn)根據(jù)正則表達(dá)式分割字符串,并以列表的形式返回,其作用與字符串對象的split()方法類似,所不同的就是分割字符由模式字符串指定。語法格式如下:

re.split(pattern, string, [maxsplit], [flags])

參數(shù)說明:

  • pattern:表示模式字符串,由要匹配的正則表達(dá)式轉(zhuǎn)換而來。
  • string:表示要匹配的字符串。
  • maxsplit:可選參數(shù),表示最大的拆分次數(shù)。
  • flags:可選參數(shù),表示標(biāo)志位,用于控制匹配方式,如是否區(qū)分字母大小寫。

例如,從給定的URL地址中提取出請求地址和各個(gè)參數(shù),代碼如下:

import re

pattern = r"[?|&]"
url = "https://study.163.com/courses-search?keyword=python&username=amo"
result = re.split(pattern, url)
print(result)

執(zhí)行結(jié)果如下:

['https://study.163.com/courses-search', 'keyword=python', 'username=amo']

關(guān)于正則表達(dá)式的貪婪非貪婪 可以點(diǎn)擊這里正則表達(dá)式的貪婪模式與非貪婪模式參考。

到此這篇關(guān)于Python使用正則表達(dá)式實(shí)現(xiàn)爬蟲數(shù)據(jù)抽取的文章就介紹到這了,更多相關(guān)Python 正則表達(dá)式數(shù)據(jù)抽取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python編程學(xué)習(xí)之如何判斷3個(gè)數(shù)的大小

    Python編程學(xué)習(xí)之如何判斷3個(gè)數(shù)的大小

    這篇文章主要給大家介紹了關(guān)于Python編程學(xué)習(xí)之如何判斷3個(gè)數(shù)的大小的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Python字典,函數(shù),全局變量代碼解析

    Python字典,函數(shù),全局變量代碼解析

    這篇文章主要介紹了Python字典,函數(shù),全局變量代碼解析,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • python光學(xué)仿真實(shí)現(xiàn)光線追跡折射與反射的實(shí)現(xiàn)

    python光學(xué)仿真實(shí)現(xiàn)光線追跡折射與反射的實(shí)現(xiàn)

    這篇文章主要為大家介紹了python光學(xué)仿真實(shí)現(xiàn)光線追跡折射與反射的實(shí)現(xiàn)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10
  • Selenium爬取b站主播頭像并以昵稱命名保存到本地

    Selenium爬取b站主播頭像并以昵稱命名保存到本地

    這篇文章主要介紹了使用Selenium自動(dòng)化爬取b站主播頭像并以昵稱命名保存到本地的方法,代碼簡單完整,對于大家練習(xí)Selenium自動(dòng)化有一定的幫助,需要的朋友可以參考下
    2021-04-04
  • python操作xml文件示例

    python操作xml文件示例

    這篇文章主要介紹了python操作xml文件示例,需要的朋友可以參考下
    2014-04-04
  • Python循環(huán)語句介紹

    Python循環(huán)語句介紹

    大家好,本篇文章主要講的是Python循環(huán)語句介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 使用Python實(shí)現(xiàn)跳一跳自動(dòng)跳躍功能

    使用Python實(shí)現(xiàn)跳一跳自動(dòng)跳躍功能

    這篇文章主要介紹了使用Python實(shí)現(xiàn)跳一跳自動(dòng)跳躍功能,本文圖文并茂通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Python單例模式實(shí)例詳解

    Python單例模式實(shí)例詳解

    這篇文章主要介紹了Python單例模式,結(jié)合實(shí)例形式分析了單例模式的概念、實(shí)現(xiàn)與使用方法、已經(jīng)相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-03-03
  • python冒泡排序簡單實(shí)現(xiàn)方法

    python冒泡排序簡單實(shí)現(xiàn)方法

    這篇文章主要介紹了python冒泡排序簡單實(shí)現(xiàn)方法,實(shí)例分析了Python冒泡排序的簡單實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • Python使用Selenium WebDriver的入門介紹及安裝教程(最新推薦)

    Python使用Selenium WebDriver的入門介紹及安裝教程(最新推薦)

    這篇文章主要介紹了Python使用Selenium WebDriver的入門介紹及安裝教程,本文使用環(huán)境為python3.11+win10 64位+firefox瀏覽器,所以本文使用的瀏覽器驅(qū)動(dòng)是Firefox的geckodriver ,如果你使用的是其他瀏覽器,那么選擇自己對應(yīng)的瀏覽器驅(qū)動(dòng)程序即可,需要的朋友可以參考下
    2023-04-04

最新評論