一 爬蟲簡介
概述
近年來,隨着網絡應用的逐漸擴展和深入,如何高效的獲取網上數據成為了無數公司和個人的追求,在大數據時代,誰掌握了更多的數據,誰就可以獲得更高的利益,而網絡爬蟲是其中最為常用的一種從網上爬取數據的手段。
網絡爬蟲,即Web Spider,是一個很形象的名字。如果把互聯網比喻成一個蜘蛛網,那么Spider就是在網上爬來爬去的蜘蛛。網絡蜘蛛是通過網頁的鏈接地址來尋找網頁的。從網站某一個頁面(通常是首頁)開始,讀取網頁的內容,找到在網頁中的其它鏈接地址,然后通過這些鏈接地址尋找下一個網頁,這樣一直循環下去,直到把這個網站所有的網頁都抓取完為止。
爬蟲的價值
互聯網中最有價值的便是數據,比如天貓商城的商品信息,鏈家網的租房信息,雪球網的證券投資信息等等,這些數據都代表了各個行業的真金白銀,可以說,誰掌握了行業內的第一手數據,誰就成了整個行業的主宰,如果把整個互聯網的數據比喻為一座寶藏,那我們的爬蟲課程就是來教大家如何來高效地挖掘這些寶藏,掌握了爬蟲技能, 你就成了所有互聯網信息公司幕后的老板,換言之,它們都在免費為你提供有價值的數據。
robots.txt協議
如果自己的門戶網站中的指定頁面中的數據不想讓爬蟲程序爬取到的話,那么則可以通過編寫一個robots.txt的協議文件來約束爬蟲程序的數據爬取。robots協議的編寫格式可以觀察淘寶網的robots(訪問www.taobao.com/robots.txt即可)。但是需要注意的是,該協議只是相當於口頭的協議,並沒有使用相關技術進行強制管制,所以該協議是防君子不防小人。但是我們在學習爬蟲階段編寫的爬蟲程序可以先忽略robots協議。
爬蟲的基本流程
預備知識
二 requests模塊
Requests是用python語言基於urllib編寫的,采用的是Apache2 Licensed開源協議的HTTP庫,Requests它會比urllib更加方便,可以節約我們大量的工作。一句話,requests是python實現的最簡單易用的HTTP庫,建議爬蟲使用requests庫。默認安裝好python之后,是沒有安裝requests模塊的,需要單獨通過pip安裝
2.1 基本語法
requests模塊支持的請求
import requests
requests.get("http://httpbin.org/get")
requests.post("http://httpbin.org/post")
requests.put("http://httpbin.org/put")
requests.delete("http://httpbin.org/delete")
requests.head("http://httpbin.org/get")
requests.options("http://httpbin.org/get")
get請求
1 基本請求
import requests
response=requests.get('https://www.jd.com/',)
with open("jd.html","wb") as f:
f.write(response.content)
2 含參數請求
import requests
response=requests.get('https://s.taobao.com/search?q=手機')
response=requests.get('https://s.taobao.com/search',params={"q":"美女"})
3 含請求頭請求
import requests
response=requests.get('https://dig.chouti.com/',
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36',
}
)
4 含cookies請求
import uuid
import requests
url = 'http://httpbin.org/cookies'
cookies = dict(sbid=str(uuid.uuid4()))
res = requests.get(url, cookies=cookies)
print(res.text)
post請求
1 data參數
requests.post()用法與requests.get()完全一致,特殊的是requests.post()多了一個data參數,用來存放請求體數據
response=requests.post("http://httpbin.org/post",params={"a":"10"}, data={"name":"yuan"})
2 發送json數據
import requests
res1=requests.post(url='http://httpbin.org/post', data={'name':'yuan'}) #沒有指定請求頭,#默認的請求頭:application/x-www-form-urlencoed
print(res1.json())
res2=requests.post(url='http://httpbin.org/post',json={'age':"22",}) #默認的請求頭:application/json
print(res2.json())
response對象
(1) 常見屬性
import requests
respone=requests.get('https://sh.lianjia.com/ershoufang/')
# respone屬性
print(respone.text)
print(respone.content)
print(respone.status_code)
print(respone.headers)
print(respone.cookies)
print(respone.cookies.get_dict())
print(respone.cookies.items())
print(respone.url)
print(respone.history)
print(respone.encoding)
(2) 編碼問題
import requests
response=requests.get('http://www.autohome.com/news')
#response.encoding='gbk' #汽車之家網站返回的頁面內容為gb2312編碼的,而requests的默認編碼為ISO-8859-1,如果不設置成gbk則中文亂碼
with open("res.html","w") as f:
f.write(response.text)
(3) 下載二進制文件(圖片,視頻,音頻)
import requests
response=requests.get('http://bangimg1.dahe.cn/forum/201612/10/200447p36yk96im76vatyk.jpg')
with open("res.png","wb") as f:
# f.write(response.content) # 比如下載視頻時,如果視頻100G,用response.content然后一下子寫到文件中是不合理的
for line in response.iter_content():
f.write(line)
(4) 解析json數據
import requests
import json
response=requests.get('http://httpbin.org/get')
res1=json.loads(response.text) #太麻煩
res2=response.json() #直接獲取json數據
print(res1==res2)
(5) Redirection and History
默認情況下,除了 HEAD, Requests 會自動處理所有重定向。可以使用響應對象的 history 方法來追蹤重定向。Response.history 是一個 Response 對象的列表,為了完成請求而創建了這些對象。這個對象列表按照從最老到最近的請求進行排序。
>>> r = requests.get('http://github.com')
>>> r.url
'https://github.com/'
>>> r.status_code
200
>>> r.history
[<Response [301]>]
另外,還可以通過 allow_redirects 參數禁用重定向處理:
>>> r = requests.get('http://github.com', allow_redirects=False)
>>> r.status_code
301
>>> r.history
[]
2.2 requests進階用法
代理
一些網站會有相應的反爬蟲措施,例如很多網站會檢測某一段時間某個IP的訪問次數,如果訪問頻率太快以至於看起來不像正常訪客,它可能就會會禁止這個IP的訪問。所以我們需要設置一些代理服務器,每隔一段時間換一個代理,就算IP被禁止,依然可以換個IP繼續爬取。
res=requests.get('http://httpbin.org/ip', proxies={'http':'110.83.40.27:9999'}).json()
print(res)
2.3 爬蟲案例
豆瓣網電影top250
github的home頁
import requests
import re
#第一步: 請求獲取token,以便通過post請求校驗
session=requests.session()
res=session.get("https://github.com/login")
authenticity_token=re.findall('name="authenticity_token" value="(.*?)"',res.text)[0]
print(authenticity_token)
# 第二步 構建post請求數據
data={
"login": "yuanchenqi0316@163.com",
"password":"yuanchenqi0316",
"commit": "Sign in",
"utf8": "✓",
"authenticity_token": authenticity_token
}
res=session.post("https://github.com/session",data=data,headers=headers,cookies=cookies)
with open("github.html","wb") as f:
f.write(res.content)