1. 程式人生 > 程式設計 >python requests庫的使用

python requests庫的使用

requests模組

  使用requests可以模擬瀏覽器的請求,requests模組的本質是封裝了urllib3模組的功能,比起之前用到的urllib,requests模組的api更加便捷

  requests庫傳送請求將網頁內容下載下來以後,並不會執行js程式碼,這需要我們自己分析目標站點然後發起新的request請求,但是selenium模組就可以執行js的操作。

安裝:

pip3 install requests  

請求方式:主要用到的就get和post兩種

#各種請求方式:常用的就是requests.get()和requests.post()
import requests

r = requests.get('https://api.github.com/events')
r = requests.post('http://httpbin.org/post',data = {'key':'value'})
r = requests.put('http://httpbin.org/put',data = {'key':'value'})
r = requests.delete('http://httpbin.org/delete')
r = requests.head('http://httpbin.org/get')
r = requests.options('http://httpbin.org/get')
#GET請求
HTTP預設的請求方法就是GET
   * 沒有請求體
   * 資料必須在1K之內!
   * GET請求資料會暴露在瀏覽器的位址列中

GET請求常用的操作:
    1. 在瀏覽器的位址列中直接給出URL,那麼就一定是GET請求
    2. 點選頁面上的超連結也一定是GET請求
    3. 提交表單時,表單預設使用GET請求,但可以設定為POST


#POST請求
(1). 資料不會出現在位址列中
(2). 資料的大小沒有上限
(3). 有請求體
(4). 請求體中如果存在中文,會使用URL編碼!


#!!!requests.post()用法與requests.get()完全一致,特殊的是requests.post()有一個data引數,用來存放請求體資料

基於GET的請求方式

一、基本請求的程式碼

import requests
response=requests.get('http://http://www.cnblogs.com/')
print(response.text)

二、GET請求的引數

  GET請求的引數放在url的問號後面,以鍵值對形式傳參

方式一:自行拼接引數(原理就是這樣,不過我們一般都用方式二的形式)

#在請求頭內將自己偽裝成瀏覽器,否則百度不會正常返回頁面內容
import requests

response=requests.get('https://www.baidu.com/s?wd=python&pn=1',#請求頭資訊
           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',})
print(response.text)


#如果查詢關鍵詞是中文或者有其他特殊符號,則不得不進行url編碼後再拼接
from urllib.parse import urlencode
wd='蒼老師'
encode_res=urlencode({'k':wd},encoding='utf-8')
keyword=encode_res.split('=')[1]#拿到編碼後的字串
print(keyword)
# 然後拼接成url
url='https://www.baidu.com/s?wd=%s&pn=1' %keyword

response=requests.get(url,headers={
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,})
res1=response.text

方式二:利用params引數(原理就是底層封裝了方式一)

#上述操作可以用requests模組的一個params引數搞定,本質還是呼叫urlencode
from urllib.parse import urlencode
wd='egon老師'
pn=1

response=requests.get('https://www.baidu.com/s',#引數進行傳參,幫我們省去了urlencode這一步
           params={
             'wd':wd,'pn':pn
           },})
res2=response.text

#驗證結果,開啟a.html與b.html頁面內容一樣
with open('a.html','w',encoding='utf-8') as f:
  f.write(res1) 
with open('b.html',encoding='utf-8') as f:
  f.write(res2)

params引數的使用

三、請求頭headers

  一般情況下,瀏覽器在傳送GET請求的時候都會有請求頭,用於放置跟客戶端有關的資訊。有些網站必須要有某些引數,這時我們在用爬蟲偽造瀏覽器傳送GET請求時就要在headers引數下設定好請求頭中會攜帶的引數

常見請求頭:

#通常我們在傳送請求時都需要帶上請求頭,請求頭是將自身偽裝成瀏覽器的關鍵,常見的有用的請求頭如下
Host
Referer  #大型網站通常都會根據該引數判斷請求的來源
User-Agent #客戶端
Cookie   #Cookie資訊包含在請求頭裡,requests模組有單獨的引數來處理他,處理後headers={}內就可以不用放置
#新增headers(瀏覽器會識別請求頭,不加可能會被拒絕訪問,比如訪問https://www.zhihu.com/explore)
import requests
response=requests.get('https://www.zhihu.com/explore')
response.status_code #500


#自己定製headers
headers={
  'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36',}
respone=requests.get('https://www.zhihu.com/explore',headers=headers)
print(respone.status_code) #200

設定請求頭的方式

四、cookie資訊

  有些要登入才能實行的功能,我們就必須在發起請求的資訊中帶上cookie,該cookie需要先由瀏覽器真實訪問後得到,不可偽造。但我們可以在瀏覽器真實訪問後將cookie資訊複製出來,在我們爬蟲發起GET請求時傳入該引數即可

#登入github,然後從瀏覽器中獲取cookies,以後就可以直接拿著cookie登入了,無需輸入使用者名稱密碼
#使用者名稱:egonlin 郵箱[email protected] 密碼lhf@123
import requests

Cookies={    'user_session':'wGMHFJKgDcmRIVvcA14_Wrt_3xaUyJNsBnPbYzEL6L0bHcfc',}

response=requests.get(        'https://github.com/settings/emails',cookies=Cookies) #github對請求頭沒有什麼限制,我們無需定製user-agent,對於其他網站可能還需要定製


print('[email protected]' in response.text) #True

  然而,每次都要先開啟瀏覽器訪問連結再講cookie複製出來是一個非常麻煩的事,真正的程式設計師怎麼可以被這個給限制住。所以,我們就要用到requests模組下的一個函式

import requests

session = requests.session()

  之後,我們每次發起GET請求的時候都用session代替requests即可,再也不必為傳cookie而煩惱啦。(從此忘記cookie也行哈哈哈)

示例程式碼:

session.get(          'https://passport.lagou.com/grantServiceTicket/grant.html',headers={
           'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/63.0.3239.132 Safari/537.36','Referer': 'https://passport.lagou.com/login/login.html',}
         )

基於POST的請求方式

  請求的程式碼與GET相同,不過因為POST請求的引數放在請求體裡,所以在傳參的時候會多一個data引數,用於放置請求的引數資訊。

'''
一 目標站點分析
  瀏覽器輸入https://github.com/login
  然後輸入錯誤的賬號密碼,抓包
  發現登入行為是post提交到:https://github.com/session
  而且請求頭包含cookie
  而且請求體包含:
    commit:Sign in
    utf8:✓
    authenticity_token:lbI8IJCwGslZS8qJPnof5e7ZkCoSoMn6jmDTsL1r/m06NLyIbw7vCrpwrFAPzHMep3Tmf/TSJVoXWrvDZaVwxQ==
    login:egonlin
    password:123


二 流程分析
  先GET:https://github.com/login拿到初始cookie與authenticity_token
  返回POST:https://github.com/session, 帶上初始cookie,帶上請求體(authenticity_token,使用者名稱,密碼等)
  最後拿到登入cookie

  ps:如果密碼時密文形式,則可以先輸錯賬號,輸對密碼,然後到瀏覽器中拿到加密後的密碼,github的密碼是明文
'''

import requests
import re

#第一次請求
r1=requests.get('https://github.com/login')
r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授權)
authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #從頁面中拿到CSRF TOKEN

#第二次請求:帶著初始cookie和TOKEN傳送POST請求給登入頁面,帶上賬號密碼
data={
  'commit':'Sign in','utf8':'✓','authenticity_token':authenticity_token,'login':'[email protected]','password':'alex3714'
}
r2=requests.post('https://github.com/session',data=data,cookies=r1_cookie
       )


login_cookie=r2.cookies.get_dict()


#第三次請求:以後的登入,拿著login_cookie就可以,比如訪問一些個人配置
r3=requests.get('https://github.com/settings/emails',cookies=login_cookie)

print('[email protected]' in r3.text) #True

自動登入github(自己處理cookie資訊)

手動處理cookie後實現自動登入github
import requests
import re

session=requests.session()
#第一次請求
r1=session.get('https://github.com/login')
authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #從頁面中拿到CSRF TOKEN

#第二次請求
data={
  'commit':'Sign in','password':'alex3714'
}
r2=session.post('https://github.com/session',)

#第三次請求
r3=session.get('https://github.com/settings/emails')

print('[email protected]' in r3.text) #True
使用requests.session()自動幫我們處理cookie資訊後自動登入GitHub

補充說明

requests.post(url='xxxxxxxx',data={'xxx':'yyy'}) #沒有指定請求頭,#預設的請求頭:application/x-www-form-urlencoed

#如果我們自定義請求頭是application/json,並且用data傳值,則服務端取不到值
requests.post(url='',data={'':1,},headers={
         'content-type':'application/json'
       })


requests.post(url='',json={'':1,) #預設的請求頭:application/json

響應Response

  response是響應資訊,具體屬性如下

import requests
respone=requests.get('http://www.jianshu.com')
# respone屬性
print(respone.text)  #包含html內容的字串
print(respone.content)#bytes型別的字串

print(respone.status_code)#狀態碼200
print(respone.headers)  #請求頭資訊
print(respone.cookies)  #COOKIE物件
print(respone.cookies.get_dict())#封裝了cookie引數的字典{'locale': 'zh-CN'}

print(respone.cookies.items())#封裝了cookie引數的列表[('locale','zh-CN')]

print(respone.url)#url地址https://www.jianshu.com/
print(respone.history)

print(respone.encoding)#編碼utf-8

#關閉:response.close()
from contextlib import closing
with closing(requests.get('xxx',stream=True)) as response:
  for line in response.iter_content():
  pass#將內容一行一行寫到檔案中

有時網頁不是utf-8的編碼,所以我們要解決編碼的問題

#編碼問題
import requests
response=requests.get('http://www.autohome.com/news')
# response.encoding='gbk' #汽車之家網站返回的頁面內容為gb2312編碼的,而requests的預設編碼為ISO-8859-1,如果不設定成gbk則中文亂碼
print(response.text)

獲取二進位制資料和二進位制流

  圖片和視訊我們獲取下來時是二進位制資料,這時我們要用wb的形式寫到本地。但有時視訊很大,我們一下子載入到記憶體再去寫入本地是不合理的,所以我們會用到二進位制流

寫二進位制資料:

import requests

response=requests.get('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1509868306530&di=712e4ef3ab258b36e9f4b48e85a81c9d&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F11385343fbf2b211e1fb58a1c08065380dd78e0c.jpg')

with open('a.jpg','wb') as f:
  f.write(response.content)

二進位制流:

#stream引數:一點一點的取,比如下載視訊時,如果視訊100G,用response.content然後一下子寫到檔案中是不合理的

import requests

response=requests.get('https://gss3.baidu.com/6LZ0ej3k1Qd3ote6lo7D0j9wehsv/tieba-smallvideo-transcode/1767502_56ec685f9c7ec542eeaf6eac93a65dc7_6fe25cd1347c_3.mp4',stream=True)

with open('b.mp4','wb') as f:
  for line in response.iter_content():
    f.write(line)

解析json資料:

#解析json
import requests
response=requests.get('http://httpbin.org/get')

import json
res1=json.loads(response.text) #太麻煩

res2=response.json() #直接獲取json資料

print(res1 == res2) #True

Redirection and History

By default Requests will perform location redirection for all verbs except HEAD.

We can use the history property of the Response object to track redirection.

The Response.history list contains the Response objects that were created in order to complete the request. The list is sorted from the oldest to the most recent response.

For example,GitHub redirects all HTTP requests to HTTPS:

>>> r = requests.get('http://github.com')

>>> r.url
'https://github.com/'

>>> r.status_code

>>> r.history
[<Response [301]>]
If you're using GET,OPTIONS,POST,PUT,PATCH or DELETE,you can disable redirection handling with the allow_redirects parameter:

>>> r = requests.get('http://github.com',allow_redirects=False)

>>> r.status_code

>>> r.history
[]
If you're using HEAD,you can enable redirection as well:

>>> r = requests.head('http://github.com',allow_redirects=True)

>>> r.url
'https://github.com/'

>>> r.history
[<Response [301]>]

先看官網的解釋

官網解釋(強行裝作看得懂的樣子)
import requests
import re

#第一次請求
r1=requests.get('https://github.com/login')
r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授權)
authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"','password':'alex3714'
}






#測試一:沒有指定allow_redirects=False,則響應頭中出現Location就跳轉到新頁面,r2代表新頁面的response
r2=requests.post('https://github.com/session',cookies=r1_cookie
       )

print(r2.status_code) #200
print(r2.url) #看到的是跳轉後的頁面
print(r2.history) #看到的是跳轉前的response
print(r2.history[0].text) #看到的是跳轉前的response.text


#測試二:指定allow_redirects=False,則響應頭中即便出現Location也不會跳轉到新頁面,r2代表的仍然是老頁面的response
r2=requests.post('https://github.com/session',cookies=r1_cookie,allow_redirects=False
       )


print(r2.status_code) #302
print(r2.url) #看到的是跳轉前的頁面https://github.com/session
print(r2.history) #[]

利用github登入後跳轉到主頁面的例子來驗證它

進階知識點

  其實學會了以上的知識,就已經可以做到用requests去爬網頁了。下面的知識是高階用法,但其實並不難。

一、SSL證書驗證

  很多大網站用的都是https,而https是要求訪問者攜帶證書的,但是其實有些不用證書也可以訪問,大多數情況都是可以攜帶也可以不攜帶證書比如知乎和百度等

但有些是有硬性要求的,則必須帶,比如對於定向的使用者,拿到證書後才有許可權訪問。例如12306

  這個時候我們在用爬蟲發起請求的時候就需要做一些手腳啦

#證書驗證(大部分網站都是https)
import requests
respone=requests.get('https://www.12306.cn') #如果是ssl請求,首先檢查證書是否合法,不合法則報錯,不允許訪問


#改進1:去掉報錯,能訪問但是會報警告,因為畢竟我們沒有證書
import requests
respone=requests.get('https://www.12306.cn',verify=False) #verify引數改成false就不驗證證書,報警告,能訪問,返回200
print(respone.status_code)#200


#改進2:去掉報錯,並且去掉警報資訊,與上步沒啥太大區別
import requests
from requests.packages import urllib3
urllib3.disable_warnings() #關閉警告
respone=requests.get('https://www.12306.cn',verify=False)
print(respone.status_code)

#改進3:加上證書
#很多網站都是https,但是不用證書也可以訪問,大多數情況都是可以攜帶也可以不攜帶證書
#知乎\百度等都是可帶可不帶
#有硬性要求的,拿到證書後才有許可權訪問某個類似12306的特定網站
import requests
respone=requests.get('https://www.12306.cn',cert=('/path/server.crt','/path/key'))#證書存放在本地
print(respone.status_code)

二、代理

  有些時候,我們用爬蟲訪問某網站請求的太頻繁時人家網站會檢測到你的不法行為然後將你的ip封掉,這樣你就不能繼續做不可告人的事啦。怎麼辦呢?我們可以用到代理。

代理的原理是:我們先發送請求到代理的IP上,然後由代理幫忙傳送。代理IP可以在網上搜,一搜一大把,但代理也是有時效性的,儘量用最新鮮的,因為老舊的可能已經被人用爛然後早就被封了。。

使用http代理的栗子:

#官網連結: http://docs.python-requests.org/en/master/user/advanced/#proxies

#代理設定:先發送請求給代理,然後由代理幫忙傳送
import requests
#代理的引數
proxies={
  'http':'http://egon:123@localhost:9743',#帶使用者名稱密碼的代理,@符號前是使用者名稱與密碼,@符號後是IP和埠
  'http':'http://localhost:9743',#不帶使用者名稱密碼的代理
  'https':'https://localhost:9743',}
respone=requests.get('https://www.12306.cn',proxies=proxies)

print(respone.status_code)

擴充套件:socks代理

  Socks 代理與應用層代理、 HTTP 層代理不同,Socks代理只是簡單地傳遞資料包,而不必關心是何種應用協議(比如FTP、HTTP和NNTP請求)。所以,Socks代理比其他應用層代理要快得多。它通常繫結在代理伺服器的1080埠上。如果在企業網或校園網上,需要透過防火牆或通過代理伺服器訪問Internet就可能需要使用SOCKS。
  一般情況下,對於撥號上網使用者都不需要使用它。我們常用的代理伺服器仍然是專門的http代理,它和SOCKS是不同的。因此,能瀏覽網頁不等於您一定可以通過SOCKS訪問Internet。 常用的防火牆,或代理軟體都支援SOCKS,但需要其管理員開啟這一功能。為了使用socks,需要了解一下內容:
  ① SOCKS伺服器的IP地址
  ② SOCKS服務所在的埠
  ③ 這個SOCKS服務是否需要使用者認證?如果需要,就要向網路管理員申請一個使用者和口令
知道了上述資訊,您就可以把這些資訊填入“網路配置”中,或者在第一次登記時填入,您就可以使用socks代理了。
  不過我們在爬蟲階段不必瞭解那麼多,我們只要知道用http代理的時候必須區分開是http請求還是https請求,因為程式碼是不同的。而利用socks代理的時候就可以五十這些,統一使用socks。

示例程式碼:

#支援socks代理,安裝:pip install requests[socks]
import requests

#用socks代替了http和https,無需特意做區分
proxies = {
  'http': 'socks5://user:pass@host:port','https': 'socks5://user:pass@host:port'
}
respone=requests.get('https://www.12306.cn',proxies=proxies)

print(respone.status_code)

三、超時時間

  有時候網路不好或者我們有相應的需求的情況下,我們要為我們的網頁載入設定一個超時時間。在過了超時時間後網頁還沒載入完就關閉此次程序

#兩種超時設定:float or tuple
#timeout=0.1 #代表接收資料的超時時間
#timeout=(0.1,0.2)#0.1代表連結的超時時間 0.2代表接收資料的超時時間

import requests
respone=requests.get('https://www.baidu.com',timeout=0.01)

四、認證設定(極不常用,瞭解即可)

  有些網站的登入框是像alert一樣彈出來的,這種型別的就無法從HTML中獲取到的,但其本質原理還是拼接成請求頭髮送的。

注:一般網站都不會使用這種形式的登入介面

r.headers['Authorization'] = _basic_auth_str(self.username,self.password)
# 一般的網站都不用預設的加密方式,都是自己寫
# 那麼我們就需要按照網站的加密方式,自己寫一個類似於_basic_auth_str的方法得到加密字串後新增到請求頭
#     r.headers['Authorization'] =func('.....')

#預設的加密方式(不過通常網站都不會用預設的加密設定)
import requests
from requests.auth import HTTPBasicAuth
r=requests.get('xxx',auth=HTTPBasicAuth('user','password'))
print(r.status_code)

#HTTPBasicAuth可以簡寫為auth
import requests
r=requests.get('xxx',auth=('user','password'))
print(r.status_code)

五、異常處理

  異常處理就是防止程式發生異常時報錯終止的

#異常處理
import requests
from requests.exceptions import * #可以檢視requests.exceptions獲取異常型別

try:
  r=requests.get('http://www.baidu.com',timeout=0.00001)
except ReadTimeout:
  print('===:')
except ConnectionError: #網路不通
  print('-----')
except Timeout:
  print('aaaaa')

except RequestException:
  print('Error')

六、上傳檔案

  上傳檔案的操作很簡單,但是其實我們在爬蟲的時候基本不會用到上傳,我們都是爬取的。

import requests
files={'file':open('a.jpg','rb')}
respone=requests.post('http://httpbin.org/post',files=files)
print(respone.status_code)

formdata格式上傳圖片

import requests
from urllib3 import encode_multipart_formdata

path = 'test1.png'

# 上傳圖片
url = 'xxxxxx'
data = {'upload':(path,open(path,'rb').read())}
header = {}
encode_data = encode_multipart_formdata(data)
file_data = encode_data[0]
header['Content-Type'] = encode_data[1]
r = requests.post(url,headers=header,data=file_data)

簡單應用

爬取拉勾網職位資訊並自動投遞簡歷:

import requests
import re

session = requests.session()

# 第一步:訪問登陸頁,拿到X_Anti_Forge_Token,X_Anti_Forge_Code
# 1、請求url:https://passport.lagou.com/login/login.html
# 2、請求方法:GET
# 3、請求頭:
#  User-agent
r1 = session.get('https://passport.lagou.com/login/login.html',)

X_Anti_Forge_Token = re.findall("X_Anti_Forge_Token = '(.*?)'",r1.text,re.S)[0]
X_Anti_Forge_Code = re.findall("X_Anti_Forge_Code = '(.*?)'",re.S)[0]
# print(X_Anti_Forge_Token,X_Anti_Forge_Code)

# 第二步:登陸
# 1、請求url:https://passport.lagou.com/login/login.json
# 2、請求方法:POST
# 3、請求頭:
#  cookie
#  User-agent
#  Referer:https://passport.lagou.com/login/login.html
#  X-Anit-Forge-Code:53165984
#  X-Anit-Forge-Token:3b6a2f62-80f0-428b-8efb-ef72fc100d78
#  X-Requested-With:XMLHttpRequest
# 4、請求體:
# isValidate:true
# username:18611453110
# password:70621c64832c4d4d66a47be6150b4a8e
# request_form_verifyCode:''
# submit:''
r2 = session.post('https://passport.lagou.com/login/login.json','X-Anit-Forge-Code': X_Anti_Forge_Code,'X-Anit-Forge-Token': X_Anti_Forge_Token,'X-Requested-With': 'XMLHttpRequest'
         },data={
           "isValidate": True,'username': '18611453110','password': '70621c64832c4d4d66a47be6150b4a8e','request_form_verifyCode': '','submit': ''
         }
         )
# 第三步:授權
# 1、請求url:https://passport.lagou.com/grantServiceTicket/grant.html
# 2、請求方法:GET
# 3、請求頭:
#  User-agent
#  Referer:https://passport.lagou.com/login/login.html

r3 = session.get('https://passport.lagou.com/grantServiceTicket/grant.html',}
         )

# 第四步:驗證
r4 = session.get('https://www.lagou.com/resume/myresume.html',}
         )

# print('18611453110' in r4.text)


# 第五步:篩選職位資訊
# 請求url:https://www.lagou.com/jobs/list_java%E9%AB%98%E7%BA%A7%E5%BC%80%E5%8F%91
# 請求方法:GET
# 請求頭:
# User-Agent
# 請求引數:
# gj:3年及以下
# px:default
# yx:25k-50k
# city:北京
from urllib.parse import urlencode

res = urlencode({'k': 'java高階開發'},encoding='utf-8').split('=')[-1]
url = 'https://www.lagou.com/jobs/list_' + res
#
# r5 = session.get(url,#         headers={
#           'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,#         },#         params={
#           'gj': '3年及以下',#           'px': 'default',#           'yx': '25k-50k',#           'city': '北京'
#         }
#         )
#
# print(r5.text)

#請求url:https://www.lagou.com/jobs/positionAjax.json
#請求方法:POST
#請求頭
#  Referer
#  User-Agent
#請求體:
  # first:true
  # pn:1
  # kd:java高階開發
#請求引數
# params={
#   'gj': '3年及以下',#   'px': 'default',#   'yx': '25k-50k',#   'city': '北京',#   'needAddtionalResult':False,#   'isSchoolJob':0
# }
r6=session.post('https://www.lagou.com/jobs/positionAjax.json',headers={
          'Referer':url,'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,data={
         'first':True,'pn':2,'kd':'java高階開發'
       },params={
         'gj': '3年及以下','px': 'default','yx': '25k-50k','city': '北京','needAddtionalResult': False,'isSchoolJob': 0
       }
       )


from pprint import pprint
# print(r6.json())
comapines_list=r6.json()['content']['positionResult']['result']
for comapiny in comapines_list:
  positionId=comapiny['positionId']
  company_link='https://www.lagou.com/jobs/{pos_id}.html'.format(pos_id=positionId)
  companyShortName = comapiny['companyShortName']
  positionName = comapiny['positionName']
  salary = comapiny['salary']
  print('''
  詳情連線:%s
  公司名:%s
  職位名:%s
  薪資:%s
  ''' %(company_link,companyShortName,positionName,salary))


  #第七步:訪問詳情頁,拿到X_Anti_Forge_Token,X_Anti_Forge_Code
  # 請求url:詳情頁地址
  # 請求方式:GET
  # 請求頭:User-Agent
  r7=session.get(company_link,headers={
          'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,}
        )
  X_Anti_Forge_Token = re.findall("X_Anti_Forge_Token = '(.*?)'",r7.text,re.S)[0]
  X_Anti_Forge_Code = re.findall("X_Anti_Forge_Code = '(.*?)'",re.S)[0]
  # print(X_Anti_Forge_Token,X_Anti_Forge_Code)


  #第八步:投遞簡歷
  #請求url:https://www.lagou.com/mycenterDelay/deliverResumeBeforce.json
  #請求方式:POST
  #請求頭:
    #Referer:詳情頁地址
    #User-agent
    #X-Anit-Forge-Code:53165984
    #X-Anit-Forge-Token:3b6a2f62-80f0-428b-8efb-ef72fc100d78
    #X-Requested-With:XMLHttpRequest
  #請求體:
  # positionId:職位ID
  # type:1
  # force:true

  session.post('https://www.lagou.com/mycenterDelay/deliverResumeBeforce.json','Referer': company_link,data={
  'positionId':positionId,'type':1,'force':True
         }
         )
  print('%s 投遞成功' %(companyShortName))

爬取獵聘網職位資訊(優化)

import re
import requests

session=requests.session()#可以幫助我們自動處理cookie資訊,我們不用再手動穿cookie的值


# 第一步:訪問登陸頁,這裡的登入頁就是首頁
# 1、請求url:https://www.liepin.com/
# 2、請求方法:GET
# 3、請求頭:
#  User-agent
r1_url='https://www.liepin.com/'
user_agent='Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/63.0.3239.108 Safari/537.36'



# 第二步:登陸
# 1、請求url:https://passport.liepin.com/c/login.json?__mn__=user_login
# 2、請求方法:POST
# 3、請求頭:
#  cookie
#  User-agent
#  Referer:https://passport.liepin.com/ajaxproxy.html
#  X-Alt-Referer:https://www.liepin.com/
#  X-Requested-With:XMLHttpRequest
# 4、請求體:
# user_pwd:5d353bc2f5474201c8a2f1891735999a
# version:
# user_login:15011316546
# chk_remember_pwd:on
r2_url='https://passport.liepin.com/c/login.json?__mn__=user_login'
r2_header_dict={
  'User-agent':user_agent,'Referer':'https://passport.liepin.com/ajaxproxy.html','X-Alt-Referer':'https://www.liepin.com/','X-Requested-With':'XMLHttpRequest'
}
r2_form_data={
  'user_pwd':'5d353bc2f5474201c8a2f1891735999a','user_login':'15011316546','chk_remember_pwd':'on'
}




# 第三步:篩選職位資訊
# 請求url:https://www.liepin.com/zhaopin/
# 請求方法:GET
# 請求頭:
# User-Agent
# 請求引數:
# salary:15$20
# dqs:010
# key:前臺
r3_url='https://www.liepin.com/zhaopin/'
r3_header_dict={
  'User-Agent':user_agent
}
# r3_params={
#   'salary':'10$20',#   'dqs':'010',#   'key':'前臺'
# }
r3_params={
  'salary':'10$20','dqs':'070020','key':'Python開發'
}



#第四步 正則匹配 拿到頁面中所有的職位資料,寫入檔案中
re_rule = 'class="icon icon-yellow-triangle".*?class="job-info".*?title="(.*?)".*?href="(.*?)" rel="external nofollow" .*?title="(.*?)".*?class="company-name".*?title="(.*?)".*?target="_blank">(.*?)</a>'
txt = '獵聘網招聘(Python1).txt'

#封裝,便於傳參
dict={
  'r1_url':r1_url,'user_agent':user_agent,'r2_url':r2_url,'r2_header_dict':r2_header_dict,'r2_form_data':r2_form_data,'r3_url':r3_url,'r3_header_dict':r3_header_dict,'r3_params':r3_params,'re_rule':re_rule,'txt':txt
}

def spider(**kwargs):
  #第一步
  r1=session.get(r1_url,headers={
            'Referer':'https://www.liepin.com/','User-Agent':user_agent
          }
          )
  #第二步
  r2=session.post(r2_url,headers=r2_header_dict,data=r2_form_data
  )
  # 第三步3
  r3=session.get(
    r3_url,headers=r3_header_dict,params=r3_params
  )
  print('國內某知名投行' in r3.text)


  #第四步
  result=re.findall(re_rule,r3.text,re.S)
  for i in result:
    a="""
    招聘職位:%s
    招聘連結:%s
    薪資及要求:%s
    公司名稱:%s
    公司型別:%s
     
    """%i
    with open(txt,'a',encoding='UTF-8') as f:
      f.write(a)




if __name__ == '__main__':
  spider(**dict)

以上就是python requests庫的使用的詳細內容,更多關於python requests庫的資料請關注我們其它相關文章!