環境python 3
anaconda
pip
以及各種庫
1.requests庫的使用
主要是如何獲得一個網頁信息
重點是
r=requests.get("https://www.google.com/?hl=zh_CN")
這里是爬取了谷歌主頁(科學上網)可以換成其他頁面爬取
import requests r=requests.get("https://www.google.com/?hl=zh_CN") print(r.status_code) r.encoding='utf-8' print(r.text)
這里是代碼部分,requests.get獲得了一個網頁的信息,存入r中
這個時候使用r.status_code如果返回200則證明調用成功,404表示失敗,其實不是200就是失敗
r.text是響應內容的字符串形式
r.encoding是從http header中猜測的響應內容編碼方式(如果header中不存在charset,則認為編碼方式為ISO-8859-1,這個時候就需要改為備選編碼中的編碼形式)
r.apparent_encoding 是從內容中分析出的響應內容編碼方式(其實較為准確)
r.content 相應內容的二進制形式(比如獲取圖像時使用)
異常處理
r.raise_for_status() 如果不是200,產生異常requests.HTTPError
加入異常處理后形成了一個爬取網頁的通用代碼框架(使得爬取更穩定)
如下:
import requests def getHTMLText(url): try: r=requests.get(url,timeout=30) r.raise_for_status() r.encoding=r.apparent_encoding return r.text except: return "產生異常" if __name__=="__main__": url="http://www.baidu.com/" print(getHTMLText(url))
為理解這個庫,需要理解HTTP
HTTP:Hypertext Transfer Protocol,超文本傳輸協議
HTTP對數據的操作與request庫是對應的
通過URL獲得資源
head方法可以通過較少的流量獲得大概信息
requests.request(method,url,**kwargs) 最后一個參數可以省略
最常使用的還是get和head,主要是get
關於爬蟲的量級
1.小規模,數據量小,爬取速度不敏感,爬取網頁,玩轉網頁為目的的 這個時候使用requests庫就可以滿足
2.中規模,數據規模較大,爬取速度敏感,爬取網站,爬取系列網站 Scrapy庫
3.爬取全網,大規模,搜索引擎比如百度,google,爬取速度關鍵,這一類的爬蟲是定制開發的而非第三方庫
下面是實踐部分,有一些網站有反爬機制,比如亞馬遜,所以需要改動我們的user-agent進行偽裝,代碼如下:
import requests def getHTMLText(url): try: # 更改頭部信息,模擬成一個瀏覽器 kv = {'user-agent': 'Mozilla/5.0'} r=requests.get(url,headers=kv,timeout=30) r.raise_for_status() r.encoding=r.apparent_encoding print(r.request.headers) return r.text[:1000] except: return "產生異常" if __name__=="__main__": url="https://www.amazon.cn/dp/B07FDT8P6C/ref=cngwdyfloorv2_recs_0?pf_rd_p=d2aa3428-dc2b-4cfe-bca6-5e3a33f2342e&pf_rd_s=desktop-2&pf_rd_t=36701&pf_rd_i=desktop&pf_rd_m=A1AJ19PSB66TGU&pf_rd_r=G32Y9X81496BTATWRG3A&pf_rd_r=G32Y9X81496BTATWRG3A&pf_rd_p=d2aa3428-dc2b-4cfe-bca6-5e3a33f2342e" print(getHTMLText(url))
包含搜索的百度爬蟲代碼,期中kv_word是提交的輸入關鍵詞,最終返回獲得的信息數量,每次略有差別,我隨便一次為319295:
import requests def getHTMLText(url): try: # 更改頭部信息,模擬成一個瀏覽器 kv_head = {'user-agent': 'Mozilla/5.0'} kv_word={'wd':'Python'} r=requests.get(url,params=kv_word,headers=kv_head,timeout=30) r.raise_for_status() r.encoding=r.apparent_encoding print(r.request.url) return len(r.text) except: return "產生異常" if __name__=="__main__": url='https://www.baidu.com/s' print(getHTMLText(url))
下面嘗試爬取圖片,主要就是用r.content轉換為二進制進行存取代碼如下:
import requests def getHTMLText(url): try: path='F:/a/abc.jpeg' # 更改頭部信息,模擬成一個瀏覽器 kv_head = {'user-agent': 'Mozilla/5.0'} r=requests.get(url,headers=kv_head,timeout=30) print(r.status_code) #將獲得的存入路徑中,r.content是二進制文件 with open(path,'wb') as f: f.write(r.content) f.close() return len(r.text) except: return "產生異常" if __name__=="__main__": url='https://b-ssl.duitang.com/uploads/item/201601/25/20160125170559_SPKF2.jpeg' print(getHTMLText(url))
下面我們嘗試通過ip138網站來提交ip相關信息,爬取ip地址所在地,
可以先手動提交一個,發現其特點:
http://www.ip138.com/ips138.asp?ip=10.3.8.211
所以我們就可以仿真這個來進行查詢
下面是代碼部分:
import requests url='http://www.ip138.com/ips138.asp?ip=' try: r=requests.get(url+'10.3.8.211') r.raise_for_status() r.encoding=r.apparent_encoding print(r.text[-500:]) except: print("爬取失敗")
這個樣例主要是幫助學習怎么用改變url的方式模擬按鍵,輸入等等操作
要學會以URL的視角看待網絡內容,也就是要以爬蟲的視角來看待網絡內容
下面就進入了解析的學習
這里需要用到的庫是beautiful soup
簡單來說主要是兩行代碼
from bs4 import BeautifulSoup
soup=BeautifulSoup('<p>data</p>',"html.parser")
就可以解析我們看到的信息
<p>...</p> 標簽Tag
現在學習獲取a標簽也就是鏈接標簽的內容的寫法,這個時候主要就是寫tag=soup.a
代碼為:
import requests from bs4 import BeautifulSoup r=requests.get("https://www.baidu.com/") demo=r.text soup=BeautifulSoup(demo,"html.parser") tag=soup.a print(tag)
執行結果為:
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">æ°é»</a>
標簽被打印出來,如果文件中有多個a標簽就只會返回第一個
如果相知道上一層是什么標簽可以使用
soup.a.parent.name
就可以獲得其上一層標簽的名字,這里接着上一個代碼寫,所以上一層獲得的返回結果為dev
下面學習怎么獲得不同屬性的值,通過
print(tag.attrs)
可以知道有哪些屬性,比如我們需要獲得class屬性的值,那么使用tag.attrs['class']
剛剛幾步實驗的代碼如下:
import requests from bs4 import BeautifulSoup r=requests.get("https://www.baidu.com/") demo=r.text soup=BeautifulSoup(demo,"html.parser") tag=soup.a print(tag.attrs) print(tag.attrs['class']) print(tag)
那么我們怎么可以獲得中間文本的值(也就是標簽內非屬性字符串)呢,這個時候就要用到
soup.a.string
標簽之間的關系如下圖:
以及一些其他的對於標簽的處理函數,如下代碼:
import requests from bs4 import BeautifulSoup r=requests.get("https://scholar.google.com/citations?hl=en&user=NoVsmbcAAAAJ") demo=r.text soup=BeautifulSoup(demo,"html.parser") tag=soup.tbody print(tag) print(tag.contents)#找到里面內容 print(len(tag.contents))#內容長度 print(tag.contents[1])#取其中的第二個數據 for child in tag.children: #遍歷兒子節點 print(child) #print(tag.attrs['class']) #print(soup.a.string)
同理.parent返回父標簽, .parents返回祖先標簽
以及還有一些平行標簽
print(tag.next_sibiling)
通過這些知識,我們可以對前后標簽進行遍歷