爬蟲基礎 簡單正則

爬蟲基礎
1.urllib.request模塊html

urlopen():打開一個給定URL字符串表示的Web鏈接,並返回文件了類型的對象
urlopen()對象的最經常使用方法:
f.read():讀取全部字節python

例子:
from urllib.request import urlopen
html = urlopen("http://pythonscraping.com/pages/page1.html")
print(html.read())
print(html.read().decode('utf-8'))git

2.Python bs4模塊:解析HTML
bs4:BeautifulSoup正則表達式

from bs4 import BeautifulSoup
from urllib.request import urlopen
html = urlopen("http://pythonscraping.com/pages/page1.html")
bsObj = BeautifulSoup(html.read(),"lxml")express

注意:bs4解析HTML標籤是沒有層級順序的,如下幾種均可行,可是推薦第二種把層級標籤所有列出來
print(bsObj.h1)
print(bsObj.html.body.h1) (推薦)
print(bsObj.body.h1)
print(bsObj.html.h1)編程

鏈接的穩定性和三種常見異常
api

 1 from urllib.request import urlopen
 2 from urllib.error import HTTPError
 3 from urllib.error import URLError
 4 from bs4 import BeautifulSoup
 5 
 6 def getTitle(url):
 7     try:
 8         html = urlopen(url)
 9     except HTTPError as e:
10         '''
11         HTTPError:服務器端沒有找到該頁面,
12         或者提取頁面時候發生錯誤
13         '''
14         print(e)
15         return None
16     except URLError as e:
17         '''
18         URLError:服務器沒找到,遠程的服務器
19         負責返回HTTP狀態編碼
20         '''
21         print(e)
22         return None 
23 
24     try:
25         bsObj = BeautifulSoup(html.read(),"lxml")
26         title = bsObj.body.h1
27     except AttributeError as e:
28         '''
29         AttributeError:屬性錯誤,試圖得到一個
30         HTML標籤,可是該標籤並不存在,BS返回
31         一個空對象,並拋出該異常
32 
33         '''
34         return None
35 
36     return title
37 
38 title = getTitle(
39     "http://pythonscraping.com/pages/page1.html")
40 
41 if title == None:
42     print("Title could not be found")
43 else:
44     print(title)

 


HTML解析
from bs4 import BeautifulSoup
bsObj = BeautifulSoup('<b id="tag1" class="boldest"> Extremely bold</b>','lxml')服務器

bsObj的幾個屬性
#返回值:
<html><body><b class="boldest" id="tag1"> Extremely bold</b></body></html>函數

bsObj.name #[document] 文件
bsObj.contents #內容:完整的HTML內容
bsObj.contents[0].name #是一級標題「HTML」測試

bsObj.body
返回值:
<body><b class="boldest" id="tag1"> Extremely bold</b></body>

bsObj.body.contents
返回值:
[<b class="boldest" id="tag1"> Extremely bold</b>]

bsObj.b
bsObj.b.contents

bsObj.string #提取文本信息


bsObj的方法

<html><body><b class="boldest" id="tag1"> Extremely bold</b></body></html>

bsObj.find('b')

bsObj.find('b',id='tag1')

如下兩種寫法均可以
bsObj.find(id='tag1')
bsObj.find('',{'id': 'tag1'})

bsObj.get_text() #做用等同於bsObj.string

#每一個標籤都有本身的name和attrs
bsObj.b.name
bsObj.b.attrs
bsObj.b['id']
bsObj.b.attrs['id']

find()和findAll()
findAll(tag,attributes,recursive,text,limit,keywords)返回一個列表
find(tag,attributes,recursive,text,keywords)返回一個bsObj

tag:HTML標籤,在<>裏面的
attributes:屬性,好比<b id="tag2">xxx</b>中的id
recursive:遞歸,是一個布爾型,True表示findAll函數還會搜索子節點,以及子節點的子節點

例子:
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")

bsObj = BeautifulSoup(html.read(),"lxml")
nameList = bsObj.findAll(text="the prince")
print(len(nameList))

 

aList = bsObj.findAll('span',class='red')
class是python中的保留字,通常推薦用字典的表達方法{'class': 'red'}
aList = bsObj.findAll('span',{'class': 'red'})


正則表達式regular expression: regex
簡介和動機
1.如何經過編程使計算機具備在文本中檢索某種模式的能力
2.爲高級的文本模式匹配、抽取、或文本形式的搜索和替換功能提供基礎
3.是一些由字符和特殊符號組成的字符串,它們描述了模式的重複或表述多個字符,因而正則表達式能按照某種模式匹配一系列有類似特徵的字符串


Python中的re模塊

.點號 用於匹配除了換行符\n之外的任何字符
例子:
f.o 在f和o之間,能夠匹配任意一個字符:fao,f9o,f#o

模版:
prog = re.compile(某個模式)
result = prog.match(字符串)

上述兩行代碼能夠合併爲一行:
m = re.match(某個模式,字符串)

m = re.match('f.o','fao')

經常使用正則表達式
| 用於分割不一樣的regex,表示或者的關係
. 匹配除了換行符\n之外的任何字符
^ 從字符串起始邊界開始匹配
$ 匹配任何以...結尾的字符串
\b 匹配任何單詞邊界 boundary
\B 與\b相反
[ ] 匹配某些特定字符
? 匹配模式出現零次或者一次
\w 匹配一個字母 word
\d 匹配一個數字 digit
+ 匹配一個或多個任何字符
{n} 前面的字符重複了n次


regex模式 匹配的字符串
at | home at、home
.. 任意兩個字符
^From 任何以From做爲起始的字符串
river$ 任何以river做爲結尾的字符串
\bthe\b 僅僅匹配單詞the
b[ui]t 匹配單詞but以及bit
\w{3} \w\w\w


例子:
m = re.match('[cr][23][dp][o2]','c3po')

m = re.match('\w\w\w-\d\d\d','abc-123')
m = re.match('\w\w\w-\d\d\d','abc-xyz')

m = re.match('\w{3}','cccsdf')

思考題:
寫出一個知足此regex的字符串,並用match函數測試
pattern = '\w+@(\w+\.)?\w+\.com'

m = re.match(pattern,'23423@qq.com')

qeru@asdf.cn.com
23423@qq.com

注意:\w匹配a-z,A-Z,0-9,包括下劃線_
記憶:與python中變量的命名規則一致

 


遍歷文檔樹的子節點

 

 1 from urllib.request import urlopen
 2 from bs4 import BeautifulSoup
 3 
 4 html = urlopen(
 5     "http://pythonscraping.com/pages/page3.html")
 6 
 7 bsObj = BeautifulSoup(html.read(),'lxml')
 8 
 9 print(bsObj.body.table.prettify())
10 
11 '''
12 #遍歷文檔樹的子節點
13 for child in bsObj.find("table",{"id":"giftList"}
14                         ).children:
15     print(child)
16 
17 
18 #遍歷文檔樹的子孫節點
19 for child in bsObj.find("table",{"id":"giftList"}
20                         ).descendants:
21     print(child)
22 
23 
24 #遍歷文檔樹兄弟節點
25 for sibling in bsObj.find("table",{"id":"giftList"}
26                         ).tr.next_siblings:
27     print(sibling)
28 
29 
30 '''
31 
32 '''
33 查找id號爲gift3的tr標籤,打印出它的next_siblings,
34 再打印出它的previous_siblings,
35 再打印出它的children
36 
37 for child in bsObj.find("tr",{"id":"gift3"}).children:
38     print(child)
39 
40 print("***********************************")
41 #遍歷文檔樹父節點
42 print(bsObj.find("img",
43     {"src":"../img/gifts/img1.jpg"})\
44     .parent.previous_sibling.get_text())
45 '''
46 
47 #使用正則表達式遍歷文檔樹
48 '''
49 使用findAll()把網頁中全部的圖片下載下來,打印出圖片的src
50 '''
51 import re
52 
53 images = bsObj.findAll("img",\
54          {"src":re.compile(\
55             "\.\.\/img\/gifts/img.*\.jpg")})
56 
57 
58 for image in images:
59     print(image["src"])
相關文章
相關標籤/搜索