爬蟲不過如此(python的Re 、Requests、BeautifulSoup 詳細篇)

網絡爬蟲(又被稱爲網頁蜘蛛,網絡機器人,在FOAF社區中間,更常常的稱爲網頁追逐者),是一種按照必定的規則,自動地抓取萬維網信息的程序或者腳本。php

爬蟲的本質就是一段自動抓取互聯網信息的程序,從網絡獲取感興趣的信息,抓取對於咱們有價值的信息,爬蟲技術是大數據和雲計算的基礎。python

爬蟲的實現可認爲是模擬瀏覽器與服務器數據交互,僞造HTTP請求。web

 

使用總覽

網頁爬取庫:正則表達式

一、urllib模塊的urllib.request       json

#基本被取代服務器

 

二、requests 第三方庫               cookie

#中小型爬蟲開發網絡

#官網:http://www.python-requests.org/en/master/框架

 

三、Scrapy 框架                         函數

#大型爬蟲開發

 

內容解析庫:

一、BeautifulSoup庫

#提取HTML和XML裏的數據   

#官網https://www.crummy.com/software/BeautifulSoup/bs4/doc/

 

二、re模塊

#正則表達式,處理字符串

 

查看網站爬蟲協議

url/robots.txt

 

requests庫基本使用

安裝: 

sudo pip3 install requests

使用介紹:

 1 import requests #導入庫
 2 
 3 
 4 #get請求數據
 5 res=requests.get("http://www.baudu.com")#get請求URL
 6 # res=requests.get("http://www.baidu.com",params={"w1":"ww11","w2":"ww22"})#get帶參數請求
 7 print(res.url)#獲取到訪問的URL
 8 
 9 
10 
11 #post請求數據
12 res=requests.post("http://www.baudu.com")#post請求URL
13 # res=requests.post("http://www.baidu.com",data={"w1":"ww11","w2":"ww22"})#post帶參數請求
14 
15 #post上傳文件
16 #filex={"img":open('dongdd/web.py','rb')}#文件表單
17 #filex={"img":("evil.jpg",open('dongdd/1.jpg','rb'))}#指定文件名更改成evil.jpg
18 filex={"img":("veil.txt","人的一切痛苦,\r\n本質上是對本身無能的憤怒!\r\n wowo")}#以文件保存字符串
19 res=requests.post(urlx,files=filex)
20 
21 
22 
23 #cookies
24 #cookie在請求頁第一次設置後是不能立刻用下列函數拿到值的,必須是請求前存在
25 
26 print(res.cookies)#打印全部cookie
27 print(res.cookies["us"])#獲取單個cookie
28 
29 #攜帶自定義cookie,可作當次頁面cookie比較驗證
30 coo={"cc1":"ccc01","cc2":"ccco2"}
31 res=ss.post("http://192.168.43.21:8080/login.php",cookies=coo)
32 
33 #自動攜帶網站上的cookie,訪問頁面,上面代碼設置cookie的不可被自動攜帶,必須每次手動
34 ss=requests.Session()
35 res=ss.post("http://192.168.43.21:8080/login.php")
36 res=ss.post("http://192.168.43.21:8080/cancel.php")#可作頁面1中cookie驗證
37 
38 
39 
40 #超時
41 #默認爲一直請求URL,處於中止狀態,因此必需要設置超時
42 res=requests.post("http://192.168.43.121:8080/login.php",timeout=0.2)#鏈接時間爲:0.2s
43 #設置鏈接超時和讀超時:timeout=(3.05, 27) #第一個爲規定鏈接時間,第二個爲規定讀取時間
44 #永遠等待相應:timeout=None
45 
46 
47 #修改或添加請求頭,請求頭的必要參數可修改
48 headx={'User-Agent': 'wwwwwwwww', 'Connection': 'xxxxxxx', 'tt': '--------'} 
49 res=requests.get("http://193.112.87.66/wx/file.php",headers=headx) 
50 print(res.request.headers)#獲取請求頭
51 
52 #其餘相關參數
53 print(res.status_code)#獲取訪問狀態碼,200(系統常量:requests.codes.ok)爲成功
54 print(res.raise_for_status())#請求錯誤時能夠打印錯誤(4XX客戶端錯誤或5XX服務器錯誤響應)
55 print(res.encoding)#查看編碼
56 res.encoding="utf-8"#更改編碼 另外值:ISO-8859-1
57 print(res.headers)#以字典形式打印相應頭,HTTP標頭名稱不區分大小寫
58 print(res.headers["date"])#print(res.headers.get("DAte"))打印出相應頭時間信息
59 print(res.text)#打印網頁源碼
60 
61 #json數據解析:
62 jsontt1=res.json()#獲得json數據
63 print(jsontt1.keys())#輸出全部json可鍵名
64 print(jsontt1["key11"])#獲取單個鍵的數據
65 
66 #二進制格式數據:res.content
67 #獲取一張網絡圖片並存儲實現:
68 res=requests.get("http://193.112.87.88/wx/img/0.jpg",timeout=5)#訪問獲得圖片數據
69 f=open("ww.jpg","wb")#以二進制方式打開文件
70 f.write(res.content)#寫入二進制數據
71 f.close()#必須關閉文件
72 
73 #從服務器獲取原始套接字響應,您能夠訪問res.raw,必須設置:stream=True
74 #數據只能使用一次(相似文件指針)
75 res=requests.get("http://193.112.87.88/wx/file.php",stream=True)
76 res.raw.read(10)#讀十個字節
77 
78 #另外一種方式獲取網頁源代碼:
79 res=requests.get("http://193.112.87.88/wx/file.php",stream=True)
80 rxx=res.raw.read(1)#讀取一個字節
81 f=open("www.txt","wb")
82 while rxx:#判斷是否爲空
83     print(rxx)
84     f.write(rxx)#寫一個字節
85     rxx = res.raw.read(1)#讀下一個字節
86 f.close();#必須關閉文件

 

re庫(正則表達式)基本使用

安裝:

python3環境自帶

 基本介紹:

一、正則表達式是獨立的語言,正則語言是共通的,好比以前寫的PHP正則裏有不少共同性

二、匹配單元介紹

轉義字符:如點表明全部字符,因此可用\.表示字符串的點

.】、【\】、【?】、【^】、【$】、【*】、【+】、【}】、【{】、【[】、【]】、【|】、【(】、【)】 

特殊符號字符:

【\d】全部數字,至關於[0-9]

【\D】全部非數字,至關於[^0-9]

【\w】任意一個字(a-z、A-Z、0-九、下劃線、中文字)

【\W】任意非字,至關於[^a-zA-Z0-9_中文字]

【.】(點)任意一個原子

【\s】全部空白(空格、tab鍵、換行),至關於[\r\t\n\f\v]

【\S】任意非空白

匹配任意一個: 

    [字符1字符2字符3]//也可爲[a-zA-Z]區間//匹配任意一個

     注意:

^】爲取反,寫在中括號內開頭處,表示除了括號裏的全部字符均可以

【^】表示普通字符,寫在括號裏除最前面的任意位置 

  括號裏的字符須要轉義,雖然有些不用轉義 

三、 匹配單元的修飾補充

【*】修飾前面的單個原子能夠出現任意次

【+】修飾前面的單個原子至少要出現1次

【?】修飾前面的單個原子只能出現0次或者1次

【{ n }】修飾前面的單個原子只能出現n次

【{a,b}】修飾前面的單個原子只能出現  [ a , b ]  次 //至少兩次用{2,  }

【|】修飾兩邊字符串任意誰總體出現,/intelligent|diligent/

【^字符1】必須以字符1開始的行,r’^xceee’必須以xceee爲開始,寫在表達式最前面

【$字符2】必須以字符2結尾的行,/\Aaa.*wo$/必須以aa開始和wo爲結束,.*表示任意

【\A和\Z】開始和結束,用法跟上相同 ,但不是以行爲結束

【\b】單詞邊界(空格),r’\bare\b’,匹配字符串「ware are xxx」匹配到are單詞,

【\B】單詞邊界之外的部分

【( )】改變優先級,r’t(r|x)ol’,可匹配trol或者txol

以小變大:r’tel*’表示l可出現任意次=>r’t(el)*’表示el可出現任意次

用於取出:r’t(el)(.*)’如"xxwtelelllll"輸出:[('el', 'elllll')]

 使用介紹:

 1 import re #導入re模塊
 2 
 3 #總體匹配
 4 str=r'To live is to live' #原字符串,r表示原始字符,如‘\n’並不會被解釋爲換行
 5 zstr=re.findall("li",str); #查找全部,返回列表
 6 print(zstr); #打印列表 輸出:['li', 'li']
 7 
 8 #用[ ]匹配其中一個
 9 str=r'live and love' 
10 zstr=re.findall("l[io]ve",str); 
11 print(zstr); #輸出:['live', 'love']
12 
13 
14 
15 
16 #方法:compile(),生成re對象
17 str=r'aawobbxxaatabbb' #原字符串
18 re_job=re.compile("a        a.*?b b",re.I|re.X)#建立re對象
19 zstr=re_job.findall(str); #使用re對象去查找
20 print(zstr); #打印列表,輸出:['aawobb', 'aatabb']
21 
22 #第二個參數值:
23 #【re.I】不區分大小寫,r’teL’可匹配tel、Tel、TEL 等
24 #【re.M】換行後不示爲同行,默認將\n換行示爲以上一行爲同一行,影響【^】【$】/^aa/使用有區別
25 #【re.S】修正表達式中【.】可匹配回車\n,如/a.*art/s匹配"I am \nsmart"
26 #【re.X】忽略正則表達式內容裏所寫的空白間隔,去掉空字符和# 後面的註釋
27 #【re.U】根據Unicode字符集解析字符。這個標誌影響 \w, \W, \b, \B
28 
29 #方法:match(),正則字符串匹配開頭
30 str=r'xxwtelelllll' #原字符串
31 zstr=re.match('xx',str); #使用re對象去查找
32 print(zstr); #輸出對象:<re.Match object; span=(0, 2), match='xx'>,未匹配到則返回None
33 if(zstr):
34     print("匹配成功")
35 else:
36     print("匹配失敗")
37 
38 #方法:search(),正則字符串匹配任意一個位置
39 str=r'wtxxelelxxllll' #原字符串
40 zstr=re.search('xx',str); #使用re對象去查找
41 print(zstr); #輸出對象:<re.Match object; span=(2, 4), match='xx'>,未匹配到則返回None
42 if(zstr):
43     print("匹配成功")
44 else:
45 print("匹配失敗")
46 
47 #方法:sub(),正則法替換字符串內容
48 str=r'--x2x--xvx--' #原字符串
49 zstr=re.sub('x.*?x','Python',str); #使用re對象去查找
50 print(zstr);#輸出:--Python--Python—
51 #將re.sub換成:re.subn()則輸出次數:('--Python--Python--', 2)
52 
53 #方法:split(),正則法拆分字符串內容
54 str=r'1+2-6/1|2^5' #原字符串
55 zstr=re.split(r'[\^\+\*\|\/\-]',str); #使用re對象去查找
56 print(zstr);#輸出:['1', '2', '6', '1', '2', '5']

 

BeautifulSoup庫基本使用

安裝:
   sudo pip3 install beautifulsoup4
使用介紹:
 1 from bs4 import BeautifulSoup#導入模塊
 2 import requests #網頁訪問庫
 3 res=requests.get("http://193.112.87.88/wx/file.php")
 4 res.encoding="utf-8"
 5 
 6 be=BeautifulSoup(res.text,"lxml")#獲得BeautifulSoup對象,lxml爲HTML解析器,如XML解析則要用xml
 7 print(be.original_encoding)#輸出編碼
 8 print(be.prettify())#以標準HTML格式輸出網頁源碼
 9 
10 print(be.input)#獲取到第一個input標籤所有內容:<input name="img" type="file"/>
11 print(be.form.input)#獲取到標籤(form)下的子標籤(input)
12 print(be.form.encode("latin-1"))#自定義編碼輸出
13 print(be.input.parent.parent)#獲取input標籤的父節點的父節點
14 print(be.input.previous_sibling)#上一個兄弟節點
15 print(be.input.next_sibling)#下一個兄弟節點
16 print(be.img)#獲取到第一個img標籤內容:<img src="img/0.jpg"/>
17 picture=be.img
18 print(picture.get('src'))#獲取該屬性值(優先考慮):img/0.jpg
19 print(be.img["src"])#直接獲取屬性值
20 
21 #獲取到標籤內容值
22 print(be.title) # <title>東小東頁</title>
23 print(be.title.text) #東小東頁
24 print(be.title.string) #東小東頁
25 
26 #函數find_all()和find()使用,參數使用是相同的
27 #參數值都可使用:字符串、列表、正則對象、True(任意值)
28 
29 print(be.find_all(class_="yzm",limit=2))#limit爲要返回的條數
30 print(be.find_all('input')) #查詢全部標籤名爲input,存入到列表
31 be.find_all(id='link2')#經過id值查找
32 print(be.find_all(type=True))#type爲true表示能夠接收任意值
33 print(be.find_all(class_="yzm"))#經過class屬性查找內容,注意class後面有下劃線
34 print(be.find_all(src=re.compile(r"img/.*?jpg")))#經過src屬性查找
35 print(be.find_all('img')[0]["src"])# img/0.jpg
36 #--------------------------------------------------
37 import re #使用正則表達式
38 for inx in be.find_all(re.compile(r"i")):#匹配帶i字母的全部標籤名
39     print(inx.name)
40 #------------------------------------------------
41 for inx in be.find_all(["input","img"]):#列表傳遞多個需匹配標籤名
42    print(inx)
43    print(inx.get("name"))#獲取標籤name屬性值
44 #------------------------------------------------------
45 
46 #找到第一個,且只找一個
47 print(be.find(type="file"))#經過屬性查找
48 print(be.find("input"))#經過標籤查找
49 print(be.find("input",type="password"))#經過標籤加屬性查找,可支持有:id、type等
50 print(be.find(text="東小東").parent)#經過text屬性查找:<legend>東小東</legend>
51 #參數不支持name和data-*
52 print(be.find_all(attrs={"name":"yzm"}))#可用此方法解決
53 
54 
55 #擴展:
56 be=BeautifulSoup(open("www.txt","rb"))#直接讀取文件內容
相關文章
相關標籤/搜索