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


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

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

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

 

使用總覽

網頁爬取庫:

1、urllib模塊的urllib.request       

#基本被取代

 

2、requests 第三方庫               

#中小型爬蟲開發

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

 

3、Scrapy 框架                         

#大型爬蟲開發

 

內容解析庫:

1、BeautifulSoup庫

#提取HTML和XML里的數據   

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

 

2、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環境自帶

 基本介紹:

1、正則表達式是獨立的語言,正則語言是共通的,比如之前寫的PHP正則里有很多共同性

2、匹配單元介紹

轉義字符:如點代表所有字符,所以可用\.表示字符串的點

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

特殊符號字符:

【\d】所有數字,相當於[0-9]

【\D】所有非數字,相當於[^0-9]

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

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

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

【\s】所有空白(空格、tab鍵、換行),相當於[\r\t\n\f\v]

【\S】任意非空白

匹配任意一個: 

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

     注意:

^】為取反,寫在中括號內開頭處,表示除了括號里的所有字符都可以

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

  括號里的字符需要轉義,雖然有些不用轉義 

3、 匹配單元的修飾補充

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

【+】修飾前面的單個原子至少要出現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"))#直接讀取文件內容



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM