目錄
1.使用request的post進(jìn)行登錄
2.審查元素查找網(wǎng)頁(yè)的用戶名和密碼的鍵名
3.get方法獲取網(wǎng)頁(yè)靜態(tài)內(nèi)容
4.查找動(dòng)態(tài)js對(duì)應(yīng)XHR響json文件(str數(shù)據(jù)格式)的網(wǎng)址接口
5.使用json.loads解碼str數(shù)據(jù)格式為python的數(shù)據(jù)類型
1.使用request的post進(jìn)行登錄
python爬蟲(chóng)使用request庫(kù)登錄網(wǎng)頁(yè)時(shí),使用post方法(密碼存儲(chǔ)在header中更安全),獲取網(wǎng)頁(yè)內(nèi)容時(shí),使用get方法(網(wǎng)址與params字符串拼接是明文)


以上參考, https://blog.csdn.net/acarsar/article/details/84866637
2.審查元素查找網(wǎng)頁(yè)的用戶名和密碼的鍵名
登錄的關(guān)鍵點(diǎn)在于要知道網(wǎng)址賬號(hào)和密碼json對(duì)應(yīng)的鍵名
比如有的網(wǎng)站用戶名和密碼的鍵名是passport,password;有的是username,password等等
通過(guò)網(wǎng)頁(yè)登錄的時(shí)候按F12,選擇network,勾選Preserve log。在name列表中找到login文件或者其它文件,點(diǎn)擊login文件,查看Headers中的request Header中的內(nèi)容,尋找含義username和password的字眼,這個(gè)就是關(guān)鍵字,然后構(gòu)造json數(shù)據(jù)結(jié)構(gòu),把賬號(hào)密碼填進(jìn)去。
如果沒(méi)有l(wèi)ogin文件,就查看其它文件的header,如果所有文件都沒(méi)有,可以查看view source,在里面搜索看看。
查看賬號(hào)和密碼的鍵名是post登錄的關(guān)鍵
postData = {
"username": "[2122@qq.com](mailto:2122@qq.com)",
"password": "123qwe",
}#username和password需要在網(wǎng)頁(yè)端登錄后按F2查看
# 使用session直接post請(qǐng)求
responseRes = gerrit.post(postUrl, data = postData, headers = header)
建議采用簡(jiǎn)書作為網(wǎng)站測(cè)試,知乎的這個(gè)關(guān)鍵字通過(guò)js加密了!
第一,先使用一個(gè)錯(cuò)誤的用戶名和密碼來(lái)登錄,這樣就可以清晰的看到這個(gè)登錄請(qǐng)求有post哪些數(shù)據(jù),post到哪個(gè)url。因?yàn)槿绻褂谜_的用戶名和密碼登錄,一旦登錄成功,就會(huì)直接跳轉(zhuǎn)到其他頁(yè)面,頁(yè)面和請(qǐng)求都會(huì)被刷新。很難找出原始的請(qǐng)求信息。

第二,在截取請(qǐng)求的地方,勾選Preserve log,保留跳轉(zhuǎn)前的請(qǐng)求數(shù)據(jù)。

截取到的請(qǐng)求如下:


# -*- coding: utf-8 -*-
import requests
userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
header = {
# "origin": "[https://passport.mafengwo.cn](https://passport.mafengwo.cn/)",
"Referer": "[https://passport.mafengwo.cn/](https://passport.mafengwo.cn/)",
'User-Agent': userAgent,
}
def mafengwoLogin(account, password):
# 馬蜂窩模仿 登錄
print ("開(kāi)始模擬登錄馬蜂窩")
postUrl = "[https://passport.mafengwo.cn/login/](https://passport.mafengwo.cn/login/)"
postData = {
"passport": account,
"password": password,
}
responseRes = requests.post(postUrl, data = postData, headers = header)
# 無(wú)論是否登錄成功,狀態(tài)碼一般都是 statusCode = 200
print(f"statusCode = {responseRes.status_code}")
print(f"text = {responseRes.text}")
if __name__ == "__main__":
# 從返回結(jié)果來(lái)看,有登錄成功
mafengwoLogin("13756567832", "000000001")
一般來(lái)說(shuō),調(diào)試期,判斷是否登錄成功的最簡(jiǎn)單的方法:就是直接打印登錄之后的text內(nèi)容,使用錯(cuò)誤的用戶名登錄,和使用正確的用戶名登錄,對(duì)比打印輸出的內(nèi)容。
以上參考:https://blog.csdn.net/zwq912318834/article/details/79571110
快速查找鍵名的方法
通過(guò)右鍵審查元素,查找用戶名的鍵名為:session[email_or_mobile_number],密碼的鍵名:session[password]


以上參考: https://blog.csdn.net/iodjSVf8U1J7KYc/article/details/78940671
3.get方法獲取網(wǎng)頁(yè)靜態(tài)內(nèi)容
可以直接把網(wǎng)址當(dāng)成一個(gè)字符串來(lái)處理,手動(dòng)拼接。
URL = "[http://gerrit.pt.mioffice.cn/changes/?q=](http://gerrit.pt.mioffice.cn/changes/?q=)" + str(change_id) + "&n=25&O=81"
#也可以構(gòu)造一個(gè)kv,放到get的params參數(shù)中
import requests
kv1={'q':'java'}
>>> r1=requests.get("[http://www.so.com/s",params=kv1](http://www.so.com/s))
>>> r1.status_code
200
>>> r1.request.url
https://www.so.com/s?q=java
4.查找動(dòng)態(tài)js對(duì)應(yīng)XHR響json文件(str數(shù)據(jù)格式)的網(wǎng)址接口
登錄后爬取網(wǎng)頁(yè),發(fā)現(xiàn)大部分是js內(nèi)容,無(wú)法直接爬取,需要執(zhí)行js腳本后才能生成,但是也可以通過(guò)api方式直接訪問(wèn),缺點(diǎn)就是需要手動(dòng)找到自己想要的內(nèi)容。
對(duì)于復(fù)雜點(diǎn),獲取內(nèi)容比較多的,“python+ selenium + 第三方瀏覽器“。
對(duì)于簡(jiǎn)單的,獲取單一信息的, 分析網(wǎng)頁(yè)元素,找出該數(shù)據(jù)的原始網(wǎng)頁(yè),提交表單,獲取不同的數(shù)據(jù),用來(lái)達(dá)到爬取的目的。
5.使用json.loads解碼str數(shù)據(jù)格式為python的數(shù)據(jù)類型
一、從網(wǎng)頁(yè)響應(yīng)中找到JS腳本返回的JSON數(shù)據(jù)
即使網(wǎng)頁(yè)內(nèi)容是由JS動(dòng)態(tài)生成加載的,JS也需要對(duì)某個(gè)接口進(jìn)行調(diào)用,并根據(jù)接口返回的JSON數(shù)據(jù)再進(jìn)行加載和渲染。
所以我們可以找到JS調(diào)用的數(shù)據(jù)接口,從數(shù)據(jù)接口中找到網(wǎng)頁(yè)中最后呈現(xiàn)的數(shù)據(jù)。
就以今日頭條為例來(lái)演示:
1、找到JS請(qǐng)求的數(shù)據(jù)接口

選擇“網(wǎng)絡(luò)”選項(xiàng)卡后,發(fā)現(xiàn)有很多響應(yīng),我們篩選一下,只看XHR響應(yīng)(如果XHR想要沒(méi)有,可以看看JS)。
(XHR是Ajax中的概念,表示XMLHTTPrequest)
然后我們發(fā)現(xiàn)少了很多鏈接,隨便點(diǎn)開(kāi)一個(gè)看看:
我們選擇city,Preview中有一串json數(shù)據(jù):(選擇preview可以看到網(wǎng)頁(yè)的具體內(nèi)容,以json文件呈現(xiàn)出來(lái),我們要找的就是這個(gè)json文件!)

我們?cè)冱c(diǎn)開(kāi)看看,原來(lái)全都是城市的列表

選擇headers,查看JS請(qǐng)求的URL(有時(shí)候可能直接就是文件名city,把鼠標(biāo)放在上面就能看到網(wǎng)址),在網(wǎng)頁(yè)中輸入這個(gè)網(wǎng)址就能拿到j(luò)son內(nèi)容, 現(xiàn)在大概了解了怎么找JS請(qǐng)求的接口的吧(拿到網(wǎng)址)

獲取到j(luò)son內(nèi)容后,還要將其轉(zhuǎn)為python的數(shù)據(jù)結(jié)構(gòu),使用json庫(kù)

import json
comments = requests.get('http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-fyfzhac1650783')
comments.encoding = 'utf-8'
print(comments)
jd = json.loads(comments.text.strip('var data=')) #移除改var data=將其變?yōu)閖son數(shù)據(jù)
print(jd['result']['count']['total'])
注釋:這里解釋下為何需要移除 var data= 因?yàn)樵讷@取時(shí)字符串前綴是包含var data=的 其不符合json數(shù)據(jù)格式 因此轉(zhuǎn)化時(shí)需將其從請(qǐng)求內(nèi)容中移除(json格式起始要是{}開(kāi)頭的)
如果數(shù)據(jù)格式(type為str)是這樣的,也可以使用json.loads()解碼,得到的就是一個(gè)list

resp = gerrit.get(URL, headers=header, allow_redirects=False)
resp.text=resp.text[4:]
print(resp.url)
data = json.loads(resp.text)
news = data[0]['branch']
print("###############")
print(resp.text)
print("###############")
print(news)
print("###############")
print(len(data))
把前4個(gè)元素去掉,只保留后面的[{...},{...},{...},{...}]這種,直接使用json的loads函數(shù)就解決了,得到了一個(gè)元素為字典的list
測(cè)試代碼(即使有無(wú)序的空格插在里面,也能解決)

json.load()加載python json格式文件
json.loads()解碼python json格式
(先加載,后解碼)
以上參考:
https://blog.csdn.net/hanchaobiao/article/details/73150405——python 爬蟲(chóng)如何獲取js里面的內(nèi)容
https://zhuanlan.zhihu.com/p/24838761——Python爬蟲(chóng)實(shí)戰(zhàn)入門五:獲取JS動(dòng)態(tài)內(nèi)容—爬取今日頭條
https://toutiao.io/posts/my6w53/preview——如何輕松爬取網(wǎng)頁(yè)數(shù)據(jù)?