1. 程式人生 > >《Python網絡數據采集》讀書筆記(三)

《Python網絡數據采集》讀書筆記(三)

正則 attrs lambda

1、正則表達式

常用符號

(1)* 匹配前面的字符、子表達式或括號裏的字符0次或多次 例如:a*b* 結果:aaa,aaabb,bb

(2)+ 匹配前面的字符、子表達式或括號裏的字符至少1次 例如:a+b+ 結果:aaab,aabb,abbb

(3)[] 匹配任意一個字符(相當於“任選一個”) 例如:[A-Z]* 結果:AP,CAP,QWER

(4)() 表達式編組(會優先運行) 例如:(a*b)* 結果:aabab,abaab,ababaaab

(5){m,n} 匹配前面的字符、子表達式或括號裏的字符m到n次 例如:a{2,3}b{2,3} 結果:aabb,aaabb,aaabbb

(6)[^] 匹配任意一個不在中括號裏的字符 例如:[^A-Z]* 結果:apple,low,qwe

(7)| 匹配任意一個由豎線分割的字符、子表達式 例如:b(a|i|e)d 結果:bad,bid,bed

(8). 匹配任意單個字符(包括符號、數字和空格等) 例如:b.d 結果:bad,b d,b$d

(9)^ 指字符串開始位置的字符或子表達式 例如:^a 結果:ap,asdl,a

(10)\ 轉義字符(把有特殊含義的字符轉換成字面形式) 例如:\.\|\\ 結果:.|\

(11)$ 經常用在正則表達式的末尾,表示“從字符串的末端匹配 例如:[A-Z]*[a-z]*$ 結果:ABCabc,zzyx,Bob

(12)?! “不包含”。通常放在字符或正則表達式前面 例如:^((?![A-Z]).)*$ 結果:no-caps-here,$y01s,a5d!ne


示例:

字母“a”至少出現一次;後面跟著字母“b”重復 5 次;後面再跟字母“c”重復任意偶數次;最後一位是字母“d”,也可以沒有。

aa*bbbbb(cc)*(d | )

識別郵箱地址。

[A-Za-z0-9\._+]+@[A-Za-z]+\.(com|org|edu|net)


2、正則表達式和BeautifulSoup

網頁上有幾個商品圖片——它們的源代碼形式:<img src="../img/gifts/img3.jpg">

如果用findAll("img")抓取所有圖片將抓到許多不需要的圖片,用正則:

# -*- coding: utf-8 -*-
import re
from urllib.request import urlopen
from bs4 import BeautifulSoup


html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bsObj = BeautifulSoup(html, 'lxml')
images = bsObj.findAll("img", {"src":re.compile("\.\.\/img\/gifts\/img.*\.jpg")})
for image in images:
    print(image["src"])

這段代碼會打印出圖片的相對路徑,都是以 ../img/gifts/img 開頭,以.jpg結尾。

運行結果:

../img/gifts/img1.jpg
../img/gifts/img2.jpg
../img/gifts/img3.jpg
../img/gifts/img4.jpg
../img/gifts/img6.jpg


3、獲取屬性

>>> image.attrs
{'src': '../img/gifts/img6.jpg'}
>>> image.attrs["src"]
'../img/gifts/img6.jpg'


4、Lambda表達式

Lambda表達式本質上就是一個函數,可以作為其他函數的變量使用。

BeautifulSoup允許我們把特定函數類型當作findAll函數的參數(必須把一個標簽作為參數且返回結果是布爾類型)。BeautifulSoup 用這個函數來評估它遇到的每個標簽對象,最後把評估結果為“真”的標簽保留,把其他標簽剔除。

soup.findAll(lambda tag: len(tag.attrs) == 2)

這行代碼會找出有兩個屬性的標簽,如下:

<div class="body" id="content"></div>

<span style="color:red" class="title"></span>


《Python網絡數據采集》讀書筆記(三)