python爬虫获取方法_小白学python爬虫:2.获得数据
在上一篇文章我我們已經完成了對網頁的分析,包括了:在源碼中數據的定位;獲取方法(xpath)。那么在獲得數據之前我們考慮的則是如何獲取源碼。
接下來我們將學習如何從服務器獲得源碼。
#寫在前面“上網”的底層原理
獲得源碼(獲得服務器響應更為準確)是爬蟲最重要的一步。本文將會為大家說明python爬蟲發起請求的正確姿勢。
2.1 一些專業名詞
url:Uniform Resource Locator(統一資源定位符),也就是我們常說的網址。“統一”即代表它的名稱是有一定規則的。第一部分:http,它是協議名稱,什么是協議呢?協議中規定了一系列在我們與服務器對話中的一些規范,說通俗點,你可以把它想象成一個關于客戶端與服務器對話之間的一個合同,在這個合同中規定了兩方在對話過程中應該遵守的一些方法或規則。我會在后文進行詳細介紹。
第二部分:服務器名稱,通常是介于“//”和第一個“/”之間,在本例中,則是"www.w3school.com.cn"。你可以把服務器想象一臺電腦,服務器名稱就是這臺電腦的名稱。
第三部分:文件存放路徑部分,在本例中則是"/tags/html_ref_urlencode.html"。既然服務器是一臺電腦,那么這個“電腦”里的文件肯定都有一個相對應的路徑,是吧。
以“http”作為基本的“訪問規范”,訪問了“www.w3school.com.cn”這臺“電腦”上的“/tags”這個路徑下的“html_ref_urlencode.html”這個文件。
當然了,我舉的這個例子只是相對基礎、簡單的一種形式。有一些部分為了方便大家理解,我適當的略去了,關于對url詳細的講解,有興趣的同學可以看看這篇文章:url詳解
服務器(host):這臺“電腦”不單單是儲存一些文件資源,它每天還要處理成千上萬的訪問。
客戶端(user-agent):我們訪問服務器的工具,一般來說就是我們每天用的瀏覽器。
2.2 與服務器“對話”
我們可以把每天的上網行為想象成是在與服務器進行“對話”,每當我們訪問一個網址的時候,你與服務器的對話就開始了:當你對某一網址進行訪問時,相當于你對這個網址的服務器說:我想要你XX路徑下的XX資源
當服務器收到你的請求后,判斷是否接受你這個請求(比如說有些東西是要你登錄賬戶后才能給你的,這時候服務器就要判斷你是否登錄)
如果你符合要求,服務器將會返回你所請求的資源
而這一套流程(我省略了一些細節部分)的一些規則、方法,則是由上文提到的通信協議所制定的。我們常見的協議有兩種:http和https。其中https是在http的基礎上對增加了對話內容進行加密的一個流程。所以我們在這里只為大家介紹http。
2.2.1 “對話”的協議:http
http:Hyper Text Transfer Protocal(超文本傳輸協議)
這個協議規定了我們與服務器對話常用的兩種方式:post和get
post是向服務器提交數據例如我們注冊賬號的時候會輸入手機號,用戶名,密碼等信息,這其實就是一個post方法,將你的賬號信息提交給服務器并由服務器存儲
還有一種是你向服務器提交一些信息,而服務器則返回相應的內容,常見的有網頁上的在線翻譯。這里我們可以用python實現在線翻譯。我會在下文給出代碼
get是向服務器“索要”資源get就是按照上文說到的url來定位資源位置然后返回相應的資源
這個是我們最常用的一個方法,在上一篇文章的實戰中我們就是用get方法獲得了含有評論的html文檔
這個協議也規定了我們與服務器對話時需要的一些信息:http header(http頭部信息)
network會記錄瀏覽器與服務器之間傳輸的所有文件,你可以看到html_ref_urlencode.html就在其中。看到這可能有些同學會好奇,為啥還有幾個png(圖片)?這是因為html文檔中對這幾個圖片進行了引用(上一篇文章中的標簽的src屬性),所以當你請求這個html文檔時,該文檔引用的圖片也會同時返回給你。
我們點擊那個html文檔,就能夠看見header信息了
一般來說,http頭部信息可以分成3個部分:general header:指出此次對話的一些概要信息。一般的,其中會包含要訪問的url,對話方法(post或者get),stauts code(服務器響應狀態碼,常見的有200(成功),403(服務器拒絕),404(請求的資源不存在))等
response header:關于服務器的一些信息。一般的,其中會包含server(服務器種類)等
request header:關于客戶端的一些信息。一般的,其中會包含accept(定義我們愿意接受服務器傳給我們的資源的類型,例如說text/html則是告訴服務器我們可以接受text/htm類型的資源),accept-encoding(資源的編碼類型),accept-language(可接受的語言),host(指定請求的服務器名稱),user-agent(你是通過哪個瀏覽器來訪問)等
根據上面的圖片,大家應該可以猜出這些header的作用:告訴對方我要什么,能夠接受什么,我這次對話的狀態是啥樣的,以及一些對話的詳細信息。
其實對于我們爬蟲來說,我們需要重點關注request header的幾個值,我會在下面詳細說明。
下面我會舉兩個例子幫助大家理解以上兩個知識點:對話方法和對話的頭部信息
#例1:get方法
import requests
url = "http://www.w3school.com.cn/tags/html_ref_urlencode.html"
header = {"accept":"image/webp,image/apng"}#python能夠以字典的格式定制request header信息
r = requests.get(url,headers=header)#使用get方法請求資源
r.status_code#查看相應狀態碼
Out[181]: 406
header = {"accept":"text/html"}
r = requests.get(url,headers=header)
r.status_code
Out[184]: 200
你可以看到,當我們傳遞給服務器兩種不同的accept值的時候,服務器的響應是不同的。第一個header告訴服務器我只接受圖片類型的資源,但是我請求的資源是一個html文檔。所以會出現406錯誤
如果我將第一次請求的資源換成圖片呢?
r = requests.get("http://www.w3school.com.cn/ui2017/wrapper.png",headers={"accept":"image/png"})
r.status_code
Out[196]: 200
所以說request header的值能夠影響服務器返回給我們的響應。
#例2:post方法
接下來我們試試post方法,以在線翻譯為目標:我們向服務器post想要翻譯的內容,服務器返回相應的翻譯。打開有道翻譯:在線翻譯_有道
進入開發者工具,選擇network
在右側輸入要翻譯的文本,然后在右側的network中點擊我用紅色方框標記出來的項
看到這一步你可能有幾個疑問:
以上兩個問題中包含了兩個我還沒有提及的知識點:url的參數查詢
xhr異步加載
這兩點我會在后面詳細講解,現在主要是感受一下post方法
import requests
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
#從network的form data中復制下來的我們要post的參數
row_data = '''i: 你好from: AUTOto: AUTOsmartresult: dictclient: fanyideskwebsalt: 1535363854099sign: 014c7769cdecc9134307ac6dbf89bb2cdoctype: jsonversion: 2.1keyfrom: fanyi.webaction: FY_BY_REALTIMEtypoResult: false'''
post_data = {}
#將psot參數處理成字典類型
for each in row_data.split("\n"):
key,value = each.split(":",1)
post_data[key] = value.replace(" ","")
header = {}從network的request header中復制下來的header參數
row_header = '''Accept: application/json, text/javascript, */*; q=0.01Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: keep-aliveContent-Length: 214Content-Type: application/x-www-form-urlencoded; charset=UTF-8Cookie: _ga=GA1.2.50802496.1533625637; OUTFOX_SEARCH_USER_ID_NCOO=1577126772.4247394; OUTFOX_SEARCH_USER_ID=241799813@10.169.0.83; JSESSIONID=aaaPu5I3Doogc8yim06vw; ___rl__test__cookies=1535363854080Host: fanyi.youdao.comOrigin: http://fanyi.youdao.comReferer: http://fanyi.youdao.com/User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36X-Requested-With: XMLHttpRequest'''
for each in row_header.split("\n"):
key,value = each.split(":",1)
header[key] = value.replace(" ","")
r = requests.post(url,data=post_data,headers=header)
import json
content = json.loads(r.content)#因為返回的內容是json格式的數據
print(content)
{'translateResult': [[{'tgt': 'hello', 'src': '你好'}]], 'errorCode': 0, 'type': 'zh-CHS2en', 'smartResult': {'entries': ['', 'hello\r\n', 'hi\r\n'], 'type': 1}}
這里要提一點,header必須要用重新定制的(也就是從開發者工具上復制過來的request header),否則會返回以下內容,原因大家可以自己去測試一下是缺少了哪個header值。因為不用的網址可能對header有不同的要求,我曾經爬過一個網址要求必須有refer值。。。
所以在實戰中,大家盡可能將header全部復制替換過去。但要注意accept值的范圍,因為如果你接受壓縮包格式的數據的話,會解析成亂碼的。
r = requests.post(url,data=post_data)
content = json.loads(r.content)
print(content)
{'errorCode': 50}
通過以上兩個例子,我們應該可以直觀的感受get方法和post方法的作用與結果了。
接下來我們來重點說request header中的幾個關鍵的值
User-Agent:這個值表示你是用哪種“工具”去訪問的服務器,下面的代碼是requests的源碼,可以看到默認的header中的user-agent是“python-requests”加上版本號,有些服務器看到這個user-agent可能會拒絕你的請求,因為你這是告訴服務器我是爬蟲,而服務器不想被爬蟲訪問而造成資源的占用或者其因為其他的原因去拒絕你的訪問。
所以我們可以將user-agent替換成瀏覽器的,這樣你就是批著瀏覽器的“皮”去訪問服務器
cookies:如果你爬的網址需要登錄才能訪問,那么一般情況下,在header中加入cookies這一值就能夠讓服務器判斷你是處于登錄狀態。具體原理我就不在這講了,因為我也不知道。
def default_user_agent(name="python-requests"):
""" Return a string representing the default user agent. :rtype: str"""
return'%s/%s'% (name, __version__)
def default_headers():
""" :rtype: requests.structures.CaseInsensitiveDict"""
return CaseInsensitiveDict({'User-Agent': default_user_agent(),
'Accept-Encoding': ', '.join(('gzip', 'deflate')),
'Accept': '*/*',
'Connection': 'keep-alive', })
關于如何使用requests定制request header(請求頭)可以參考:快速上手 - Requests 2.18.1 文檔
#實戰:偽裝成瀏覽器訪問并登陸知乎
import requests
url = 'https://www.zhihu.com'
r = requests.get(url)
r.status_code
Out[415]: 400
使用默認requests的默認header的話直接是400(bad request)
header = {}
row_header = '''accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
accept-language: zh-CN,zh;q=0.9
cache-control: max-age=0
cookie: 省略。。這個不能貼出來
referer: https://www.zhihu.com
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36'''
for each in row_header.split('\n'):
key,value = each.split(":",1)
header[key] = value.replace(" ","")
loged_r = requests.get(url,headers=header)
html = loged_r.content.decode(loged_r.encoding)
loged_r.status_code
Out[416]: 200
大家可以把html復制到txt讓改成html后綴,再用瀏覽器打開,可以看到自己的頭像哦
以上
歡迎大家評論,一起進步
總結
以上是生活随笔為你收集整理的python爬虫获取方法_小白学python爬虫:2.获得数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lottie动画_神器基于Lottie的
- 下一篇: python cnn_使用python中