Python網絡爬蟲與信息提取——正則表達式
正則表達式的語法
正則表達式的常用操作符 |
||
操作符 | 說明 | 實例 |
. |
表示任何單個字符 |
? |
[] |
字符集,對單個字符給出取值范圍 | [abc]表示a、 b、c, [a-z]表示a到z單個字符 |
[^ ] | 非字符集,對單個字符給出排除范圍 | [^ abc]表示非a或b或c的單個字符 |
* |
前一個字符0次或無限次擴展 | abc*表示ab、abc、abcc、 abccc等 |
+ |
前一個字符1次或無限次擴展 | abc+表示abc、abcc、 abccc等 |
? |
前一個字符0次或1次擴展 | abc?表示ab、abc |
| |
左右表達式任意一個 |
abc|def表示abc、def |
{m} | 擴展前一個字符m次 | ab{2}c表示abbc |
{m,n} | 擴展前一個字符m至n次(含n) |
ab{1,2}c表示abc、 abbc |
^ |
匹配字符串開頭 | ^abc表示abc且在一 個字符串的開頭 |
$ |
匹配字符串結尾 | abc$表示abc且在一個 字符串的結尾 |
() |
分組標記,內部只能使用|操作符 | (abc)表示abe, (abcldef)表示abe、 def |
\d |
數字,等價于[0-9] |
? |
\w |
單詞字符,等價于[A-Za-z0-9_] |
? |
Re庫的基本使用
raw string類型(原生字符串類型)
1.用原生字符串類型不用專義,如r'\d+\w{3}'?
2.不用原生字符串類型,如‘\\d+\\w{3}’
?
Re庫主要功能函數 |
|
函數 | 說明 |
re.search() | 在一個字符串中搜索匹配正則表達式的第一個位置, 返回match對象 |
re.match() | 從一個字符串的開始位置起匹配正則表達式,返回match對象 |
re.findall() | 搜索字符串,以列表類型返回全部能匹配的子串 |
re.split() | 將一個字符串按照正則表達式匹配結果進行分割,返回列表類型 |
re.finditer() | 搜索字符串,返回一個匹配結果的選代類型,每個迭代元素是match對象 |
re.sub() | 在一個字符串中替換所有匹配正則表達式的子串,返回替換后的字符串 |
?
1.re.search(pattern, string, flags=0)
在一個字符串中搜索匹配正則表達式的第一個 位置,返回match對象。
◆pattern:正則表達式的字符串或原生字符串表示
◆string:待匹配字符串
◆flags:正則表達式使用時的控制標記
flags:正則表達式使用時的控制標記 | |
常用標記 | 說明 |
re.I? ?re.IGNORECAS | 忽略正則表達式的大小寫,[A-Z]能夠匹配小寫字符 |
re.M re.MULTILINE | 正則表達式中的^操作符能夠將給定字符串的每行當作匹配開始 |
re.S re.DOTALL |
正則表達式中的操作符能夠匹配所有字符,默認匹配除換行外的所有字符 |
import re
match = re.search(r'[1-9]\d{5}','bat 100081')
if match:
print match.group(0) ##100081
?
2.re. match(pattern, string, flags=0)
從一個字符串的開始位置起匹配正則表達式,返回match對象。
◆pattern:正則表達式的字符串或原生字符串表示
◆string:待匹配字符串
◆flags: 正則表達式使用時的控制標記
import re
match = re.match(r'[1-9]\d{5}','bit 100081')
if match:
print match.group(0)
match = re.match(r'[1-9]\d{5}','100081 bit')
if match:
print match.group(0) #100081
3.re.findall(pattern, string, flags=0)
搜索字符串,以列表類型返回全部能匹配的子串。
◆pattern:正則表達式的字符串或原生字符串表示
◆string;待匹配字符串
◆flags:正則表達式使用時的控制標記
ls = re.findall(r'[1-9]\d{5}','bit100081 tsu100084')
print ls #['100081', '100084']
4.re.split(pattern, string, maxsplit=0, flags=0)
將一個字符串按照正則表達式匹配結果進行分割,返回列表類型。
◆pattern:正則表達式的字符串或原生字符串表示
◆string:待匹配字符串
◆maxsplit:最大分割數,剩余部分作為最后一個 元素輸出
◆flags:正則表達式使用時的控制標記
print re.split(r'[1-9]\d{5}','bit100081 tsu100084')
#['bit', ' tsu', '']
print re.split(r'[1-9]\d{5}','bit100081 tsu100084', maxsplit=1)
#['bit', ' tsu100084']
?
5.re.finditer(pattern, string, flags=0)
搜索字符串,返回一個匹配結果的迭代類型,每個迭代元素是match對象。
◆pattern:正則表達式的字符串或原生字符串表示
◆string:待匹配字符串
◆flags:正則表達式使用時的控制標記
for m in re.finditer(r'[1-9]\d{5}','bit100081 tsu100084'):
if m:
print m.group(0)
#100081
#100084
?
6.re.sub(pattern, repl, string, count=0, flags=0)
在一個字符串中替換所有匹配正則表達式的子串,返回替換后的字符串。
◆pattern: 正則表達式的字符串或原生字符串表示
◆repl:替換匹配字符串的字符串
◆string:待匹配字符串
◆count:匹配的最大替換次數
◆flags:正則表達式使用時的控制標記
print re.sub(r'[1-9]\d{5}',':zipcode','bit100081 tsu100084')
#bit:zipcode tsu:zipcode
Re庫的另一種等價用法:
pat = re.compile(r'[1-9]\d{5}')
res = pat.search('bit 100081')
regex = re.compile(pattern, flags=0)
將正則表達式的字符串形式編譯成正則表達式對象
◆pattern:正則表達式的字符串或原生字符串表示
◆flags:正則表達式使用時的控制標記
?
Re庫的match對象
match對象的屬性 |
|
屬性 | 說明 |
.string | 待匹配的文本 |
.re | 匹配時使用的pattern對象(正則表達式) |
.pos | 正則表達式搜索文本的開始位置 |
.endpos |
正則表達式搜索文本的結束位置 |
?
Match對象的方法 | |
方法 | 說明 |
.group(0) | 獲得匹配后的字符串 |
.start() | 匹配字符串在原始字符串的開始位置 |
.end() | 匹配字符串在原始字符串的結束位置 |
.span() | 返回(.start(), .end()) |
m = re.search(r'[1-9]\d{5}','bit100081 tsu100084')
print m.string #bit100081 tsu100084
print m.re #<_sre.SRE_Pattern object at 0x10854d7b0>
print m.pos #0
print m.endpos #19
print m.group(0) #100081
print m.start() #3
print m.end() #9
print m.span() #(3,9)
?
實例:淘寶商品信息定向爬蟲
def gethtmltext(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def parsepage(ilt, html):
try:
plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"', html)
tlt = re.findall(r'\"raw_title\"\:\".*?\"', html)
for i in range(len(plt)):
price = eval(plt[i].split(':')[1])
title = eval(tlt[i].split(':')[1])
ilt.append([price, title])
except:
print ""
def printgoodslist(ilt):
tplt = "{:4}\t{:8}\t{:16}"
print tplt.format("序號", "價格", "商品名稱")
count = 0
for g in ilt:
print tplt.format(count, g[0], g[1])
def main():
goods = '書包'
depth = 2
start_url = 'https://s.taobao.com/search?q=' + goods
infolist = []
for i in range(depth):
try:
url = start_url + '&s=' + str(44+i)
html = gethtmltext(url)
parsepage(infolist, html)
except:
continue
printgoodslist(infolist)
main()
實例:股票數據定向爬蟲
def gethtmltext(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def getstocklist(lst, stockurl):
html = gethtmltext(stockurl)
soup = BeautifulSoup(html, 'html.parser')
a = soup.find_all('a')
for i in a:
try:
href = i.attrs['href']
lst.append(re.findall(r"[s][hz]\d{6}", href))
except:
continue
def getstockinfo(lst, stockurl, fpath):
for stock in lst:
url = stockurl + stock + '.html'
html = gethtmltext(url)
try:
if html == "":
continue
infodict = []
soup = BeautifulSoup(html, 'html.parser')
stockinfo = soup.find('div', attrs={'class':'stock-bets'})
name = stockinfo.find_all(attrs={'class':'bets-name'})[0]
infodict.update({'股票名稱':name.text.split()[0]})
keylist = stockinfo.find_all('dt')
valuelist = stocklist.find_all('dd')
for i in range(len(keylist)):
key = keylist[i].text
val = valuelist[i].text
infodict[key] = val
with open(fpath, 'a', encoding='utf-8') as f:
f.write(str(infodict) + '\n')
def main():
stock_list_url = 'http://quote.eastmoney.com/stocklist.html'
stock_info_url = 'https://gupiao.baidu.com/stock'
output_file = './baiduinfostock.txt'
slist = []
getstocklist(slist, stock_list_url)
getstockinfo(slist, stock_info_url, output_file)
main()
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
