【根據北京理工大學嵩天老師「Python網絡爬蟲與信息提取」慕課課程編寫html
慕課連接:https://www.icourse163.org/learn/BIT-1001870001?tid=1002236011#/learn/announce】python
1、網絡爬蟲引起的問題瀏覽器
爬蟲依據獲取數據的速度和能力,分爲小型、中型和大型的爬蟲。小型爬蟲能夠用python語言的Requests、BeautifulSoup庫編寫,適合獲取頁面內容;中型爬蟲能夠用Scrapy庫編寫,適合爬取網站或系列網站數據;大型爬蟲指的是搜索引擎,像百度、Google等搜索引擎都有大型爬蟲的支持,能夠爬取全網絡的信息,這種爬蟲是定製開發的,沒有第三方庫支持。服務器
網站搭建使用的Web服務器有必定的性能,若是爬蟲大量地訪問並獲取服務器的資源數據,就會削弱服務器的性能。服務器是對用戶提供數據資源服務的,它接受人類的瀏覽器訪問。可是爬蟲卻能夠憑藉計算機的高速計算能力,大量地對服務器進行訪問並獲取數據,這對服務器來講是一種負擔。此外,爬蟲獲取數據存在必定的法律風險和隱私泄露的風險。網絡
大部分網站對爬蟲有必定的限制,主要是經過兩種方法。一是檢查來訪HTTP協議頭的User-Agent字段,只響應瀏覽器或友好爬蟲的訪問請求。瀏覽器訪問網站的HTTP頭信息中會有User-Agent字段,用於標識瀏覽器的信息,如'User-Agent':'Mozilla/5.0'表示這是「Mozilla瀏覽器」。爬蟲程序訪問網站時,User-Agent字段一般都會標識程序的相關信息,而不會是瀏覽器的相關信息。若是訪問請求的HTTP信息頭中存在'User-Agent':'Mozilla/5.0',則網站認爲此次訪問是人使用瀏覽器進行的,而不會認爲是爬蟲行爲。如今不少瀏覽器的User-Agent字段都有Mozilla的標識,這裏面還有一段有趣的故事,請查看:https://zhidao.baidu.com/question/1767408752449075980.html。這種檢測爬蟲方式的缺點是,爬蟲程序能夠很容易地更改本身的User-Agent字段,從而騙取服務器,將本身的爬取行爲假裝成瀏覽器的正常訪問行爲。第二種限制爬蟲的方式是發佈robots協議。它實際上是一個txt文件,由各個網站的管理員發佈。在這個robots.txt文件中說明了網站不容許哪些爬蟲爬取哪些數據。app
2、robots協議ide
robots(robots exclusion standard,網絡爬蟲排除標準),是一個txt文件,放在網站的根目錄下。以簡潔的語法告知爬蟲程序和其編寫者,在這個網站中,有哪些數據是不能爬取的。性能
如:https://www.cnblogs.com/robots.txt 博客園的robots協議
網站
其中,User-Agent:*表示對全部的爬蟲來講。Allow:/表示能夠爬取根目錄下的任何數據。也就是說,任何爬蟲均可以爬取博客園的任何數據。ui
https://www.jd.com/robots.txt 京東的robots協議
User-Agent:*,Disallow:/?*表示不容許任何爬蟲爬取根目錄下以問號(?)開頭的任何數據,Disallow:/pop/*.html表示不容許爬取pop文件夾下全部的html文件,Disallow:/pinpai/*.html?*表示不容許爬取pinpai文件夾下任何後綴名開頭是html?的文件。除了User-Agent:*以外,還對4個特定的爬蟲進行了限制(EtaoSpider,HuihuiSpider,GwdangSpider,WochachaSpider)。在這4個爬蟲下,都有Disallow:/表示不容許這4個爬蟲爬取任何數據。
http://www.moe.edu.cn/robots.txt 中國教育部網站的robots協議(無robots協議)
中國教育部的網站沒有robots協議,表示對爬蟲的爬取行爲沒有做規定。
robots協議是網站對爬蟲和其編寫者的聲明,告知對於該網站哪些數據能夠爬取,哪些則不能夠。這個協議雖然不是約束性的,但若是違反有可能要承擔法律責任,特別是爬取來的數據涉及隱私或重大機密,或用於商業盈利目的。對於編寫爬蟲的練習者來講,要在不影響、不危害網站服務器的前提下,遵照法律、道德,遵照網站相關規定,合理、有節制地使用爬蟲程序。
3、Requests庫編寫爬蟲實戰
1.淘寶檯燈商品頁面爬取
上面的訪問是正常的,也能夠輸出頁面信息。但對於一些對請求訪問有檢查的網站來講,要更改請求HTTP信息頭中的User-Agent字段,才能夠成功鏈接至網站服務器。
最終代碼及運行結果以下:
1 #淘寶商品頁面爬取程序 2 import requests 3 4 def getHTMLText(url): 5 try: 6 kv={'User-Agent':'Mozilla/5.0'} #修改headers頭信息,模擬瀏覽器訪問行爲 7 r=requests.get(url,headers=kv) 8 r.raise_for_status() #若是狀態不是200,產生HTTPError異常 9 r.encoding=r.apparent_encoding 10 return r.text[1000:2000] 11 except: 12 return "" 13 14 def main(): 15 url="https://detail.tmall.com/item.htm?spm=a230r.1.14.20.5e6b648aNUbhlg&id=529733642155&ns=1&abbucket=1&sku_properties=3064956:9115665" 16 print(getHTMLText(url)) 17 18 if __name__=="__main__": 19 main()
2.bing搜索關鍵詞提交
在bing、百度等搜索引擎的搜索欄中輸入要查詢的內容,就會返回相應的信息。也能夠直接在URL的地址中輸入搜素關鍵字。根據這一點,能夠在程序中提交搜索關鍵字,直接返回頁面信息。
查看地址欄,能夠看到bing搜索引擎的URL是https://cn.bing.com。輸入完關鍵字後變成了https://cn.bing.com/search?q=keyword。其中keyword就是要輸入的關鍵字,這裏是檯燈或者水杯。
根據bing搜索引擎的這種查詢格式,編寫代碼:
1 #搜索引擎關鍵字提交 2 import requests 3 4 def getHTMLText(): 5 keyword="檯燈" 6 try: 7 kv={'q':keyword} 8 #params參數將添加到URL中,做爲URL鏈接的一部分 9 r=requests.get("https://cn.bing.com/search?",params=kv) 10 r.raise_for_status() #若是狀態不是200,引起HTTPError異常 11 r.encoding=r.apparent_encoding 12 return r.text[60000:65000] 13 except: 14 return "" 15 16 def main(): 17 print(getHTMLText()) 18 19 20 if __name__=="__main__": 21 main()
3.圖片抓取
圖片在網絡上以二進制形式存儲,在獲取圖片資源後也以二進制形式寫入到本地磁盤中。在網絡中找到一張圖片,右鍵能夠得到該圖片的URL地址,這個地址就是用程序爬取時用到的URL。
1 #圖片抓取程序 2 import requests 3 import os #要寫入圖片到本地磁盤,引入os庫 4 5 url="http://syds.ngchina.cn/resc/img/difang1.jpg" #圖片的URL連接 6 root="C://pics/" #存放圖片的文件夾 7 #圖片在本地磁盤中的路徑 8 #使用split('/')以反斜槓爲標誌將url分割,取最後一個字符串(即difang1.jpg) 9 #與前面的root("C://pics/")相鏈接,造成圖片在本地磁盤中的路徑 10 #這句代碼起到的效果是,用圖片原來的名字保存 11 path=root+url.split('/')[-1] 12 13 try: 14 if not os.path.exists(root): #若是root路徑(一個文件夾)不存在,則建立 15 os.mkdir(root) 16 if not os.path.exists(path): #若是path路徑不存在(即圖片不在本地磁盤中) 17 r=requests.get(url) 18 with open(path,'wb') as f: 19 f.write(r.content) #將Response對象的信息以二進制形式寫入磁盤 20 f.close() 21 print("圖片保存成功") 22 else: 23 print("圖片已存在") #path已存在(即圖片已經保存在本地磁盤中) 24 except: 25 print("圖片抓取失敗")
python語言的文件相關知識,請參考:http://www.runoob.com/python3/python3-os-file-methods.html。
4.IP地址的查詢
在網絡上有相關軟件或網站能夠查詢到IP地址,都是經過人機界面交互的形式進行的。如:http://www.ip138.com/。
查詢IP後,URL連接發生變化。與搜索引擎關鍵字提交相似,根據這樣的變化編寫程序:
1 #IP地址查詢 2 import requests 3 url="http://www.ip138.com/ips138.asp?ip=" 4 try: 5 r=requests.get(url+'114.221.176.156') #前面的URL再加上要查詢的IP 6 r.raise_for_status() #若是狀態不是200,產生HTTPError異常 7 r.encoding=r.apparent_encoding 8 print(r.text[7000:7500]) #返回包含地址信息的字符串區間 9 except: 10 print("查詢失敗")