Python爬蟲(chóng):賬號(hào)密碼登入扇貝

寫(xiě)在前面的話

網(wǎng)上的教程都太簡(jiǎn)單了(代碼又太難了),我摸索了好一陣。所以這是一個(gè)特別啰嗦的教程怜珍,每一步都有截圖。

整個(gè)流程:

  • 確保你的庫(kù)都全了
  • 用賬號(hào)密碼登入網(wǎng)頁(yè)
  • 取讀煉句信息
  • 清洗數(shù)據(jù)
  • 保存數(shù)據(jù)到Excel
  • 附完整代碼
代碼運(yùn)行界面

老規(guī)矩:安裝庫(kù)

import requests
import json
import re
import xlwt

確認(rèn)一下凤粗,你有沒(méi)有requestsxlwt的庫(kù)酥泛,沒(méi)有的話,裝一下
如果不裝嫌拣,代碼運(yùn)行不起來(lái)柔袁,你雙擊.py文件,就直接閃退了
如果你在調(diào)試中運(yùn)行异逐,那會(huì)報(bào)錯(cuò)

安裝`requests`的界面如下

賬號(hào)密碼登入

基本步驟:
(1)獲取網(wǎng)址捶索,得到【URL】
(2)輸入賬號(hào)密碼,得到【data】
(3)構(gòu)建Request Headers灰瞻,得到【headers】
(4)登入網(wǎng)頁(yè)

(1)URL

首先腥例,網(wǎng)頁(yè)類(lèi)型分為兩種辅甥,靜態(tài)和動(dòng)態(tài)的

靜態(tài)頁(yè)面 動(dòng)態(tài)頁(yè)面
非結(jié)構(gòu)化數(shù)據(jù):HTML 結(jié)構(gòu)化數(shù)據(jù):json,xml等
處理方式:正則表達(dá)式燎竖,xpath, beautifulsoup4 處理方式:直接轉(zhuǎn)化為python類(lèi)型

以扇貝網(wǎng)為例璃弄,瀏覽器為360極速瀏覽器
網(wǎng)址:
https://web.shanbay.com/web/account/login
扇貝網(wǎng)里面,部分網(wǎng)頁(yè)是靜態(tài)的构回,部分是動(dòng)態(tài)的

右擊“審查元素”夏块,或者F12,打開(kāi)開(kāi)發(fā)人員工具
點(diǎn)擊“Network”纤掸,把Preserve Log勾選上拨扶,在左下角那個(gè)框里輸入“l(fā)ogin”(表示只看登入信息)

輸入賬號(hào)密碼,登入網(wǎng)頁(yè)

登入后茁肠,顯示如下

在這里可以看到,其實(shí)我們實(shí)際登入的網(wǎng)址是
https://apiv3.shanbay.com/bayuser/login
請(qǐng)求方式是POST

補(bǔ)充缩举,請(qǐng)求方式Request Method一般有兩種垦梆,GET和POST

  • GET: 請(qǐng)求的URL會(huì)附帶查詢參數(shù)
  • POST: 請(qǐng)求的URL不會(huì)附帶查詢參數(shù)

所以第一步,明確仅孩,我們是POST請(qǐng)求托猩,網(wǎng)址是https://apiv3.shanbay.com/bayuser/login

postUrl = 'https://apiv3.shanbay.com/bayuser/login'

(2)包含賬號(hào)密碼的data

剛剛那個(gè)界面,往下滑到最后
我們看到辽慕,請(qǐng)求是Request Payload京腥,里面包含了我們賬號(hào)密碼的信息

還有一種方式是Form Data,具體區(qū)別可參考
HTTP請(qǐng)求中的form data和request payload的區(qū)別
我們這里就講Request Payload溅蛉,現(xiàn)在扇貝用這個(gè)

PayloadData  = {
                 'account': "1********9",
                 'code_2fa': "",
                 'password': "Z*************6"       
                }

(3)headers

還是剛剛那個(gè)界面公浪,網(wǎng)上翻一點(diǎn),就能看到Request Header船侧,我們選取其中部分信息欠气,構(gòu)造一個(gè)頭

我們選這3個(gè)數(shù)據(jù),自己假裝構(gòu)建一個(gè)Request Header

payloadHeader = {'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
                 'referer': "https://web.shanbay.com/web/account/login/",
                 'content-type': 'application/json'
                 }

(4)登入網(wǎng)頁(yè)

把剛剛得到的URL镜撩、Data预柒、headers整合起來(lái)

import requests # 獲取網(wǎng)頁(yè)的強(qiáng)大工具
import json  # 動(dòng)態(tài)網(wǎng)頁(yè)要用

payloadHeader = {'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
                 'referer': "https://web.shanbay.com/web/account/login/",
                 'content-type': 'application/json'
                 }

postUrl = 'https://apiv3.shanbay.com/bayuser/login'
s = requests.Session()  # 為了保存登入信息

PayloadData  = {
                 'account': "1******9",
                 'code_2fa': "",
                 'password': "Z*******6"       
                }
r = s.post(postUrl, data=json.dumps(PayloadData), headers=payloadHeader)
# s.post,表示POST請(qǐng)求

這時(shí)候輸出r的內(nèi)容袁梗,就能看到自己的昵稱(chēng)宜鸯、ID、用戶名等等遮怜,那就說(shuō)明淋袖,我們登入成功啦

這時(shí)候,我們已經(jīng)把登入的信息锯梁,保存在s 里面了

爬取煉句

如何獲取網(wǎng)頁(yè)接口

還是剛剛的開(kāi)發(fā)模式适贸,打開(kāi)我們想要爬取的網(wǎng)頁(yè)灸芳,然后看實(shí)際我們要獲取的網(wǎng)頁(yè)是什么?(我們獲取的網(wǎng)頁(yè)拜姿,和顯示的網(wǎng)頁(yè)烙样,不是同一個(gè))
比如扇貝上面顯示的是:
https://www.shanbay.com/sentence/book/all/常用/?id=10
但實(shí)際上是:
https://www.shanbay.com/api/v1/sentence/book/phrase/10/?_=1559715369583

這里發(fā)現(xiàn),獲取方式蕊肥,變成GET了谒获。
剛剛我們講了POST,現(xiàn)在就換成GET
我們輸網(wǎng)址的時(shí)候壁却,后面那個(gè)?_155.....不需要輸入批狱,是一個(gè)時(shí)間戳

url = 'https://www.shanbay.com/api/v1/sentence/book/phrase/10'
GetUrl = s.get(url)  # 這里換成get了,剛剛是s.post
TextWeb = GetUrl.text
print(TextWeb)

數(shù)據(jù)已經(jīng)都取讀了展东,只不過(guò)在系統(tǒng)儲(chǔ)存的時(shí)候赔硫,都是編碼\u02cc\這種,轉(zhuǎn)成文字就好啦~
這里有個(gè)小技巧盐肃,可以一鍵轉(zhuǎn)換爪膊,后面會(huì)講

這爬出來(lái)的網(wǎng)頁(yè),密密麻麻砸王,眼花繚亂推盛,看不懂怎么辦?
這時(shí)候谦铃,你可以點(diǎn)Preview耘成,這里面就好看很多

這和我們得到的數(shù)據(jù)是一致的,只是我們的數(shù)據(jù)需要轉(zhuǎn)換

清洗數(shù)據(jù):短語(yǔ)和單詞

短語(yǔ)和單詞相對(duì)簡(jiǎn)單一點(diǎn)驹闰,可以在網(wǎng)頁(yè)上直接讀取
(1)re.findall所有值

DataList = re.findall("{\"content.*?}",TextWeb)

我們通過(guò)re.findall得到的數(shù)據(jù)是有規(guī)律的瘪菌,每一個(gè)短語(yǔ),都相當(dāng)于一個(gè)字典
里面包含了contentdefinition兩部分的數(shù)據(jù)嘹朗,可以一鍵提取喲~

(2)把數(shù)據(jù)轉(zhuǎn)成字典
大家可以看到控嗜,實(shí)際上,這時(shí)候的類(lèi)型骡显,是一個(gè)str字符串疆栏,我們要轉(zhuǎn)化成字典,才方便操作

phrase_dict = json.loads(phrase)  #用json.load就可以直接轉(zhuǎn)換
sheet.write(j, 0, phrase_dict['content'])  #然后就可以直接提取字典內(nèi)容惫谤,保存到Excel
sheet.write(j, 1, phrase_dict['definition'])

這時(shí)候提取的數(shù)據(jù)壁顶,就很完美啦~

清洗數(shù)據(jù):煉句

煉句的獲取,比句子和短語(yǔ)稍微麻煩一點(diǎn)
因?yàn)樗畛醌@得的網(wǎng)頁(yè)溜歪,是一個(gè)匯總若专。比如有30課煉句,它就提供了30個(gè)鏈接蝴猪。
你需要先獲取鏈接调衰,然后再進(jìn)入各個(gè)網(wǎng)頁(yè)提取數(shù)據(jù)

for article in article_List:
    article_dict = json.loads(article)
    article_id = article_dict['article_id']
    article_id_url = book_article_url+"/"+str(article_id)
    Text_article_id = GetTextWeb(article_id_url,s)
    
    content_article_1 = re.findall(" {\"zh-CN\": {\"content.*?}",Text_article_id)
    for content1 in content_article_1:        
        content1 = content1[len("{\"zh-CN\":")+2:]
        content_dict_1 = json.loads(content1)
        sheet.write(m, 1, content_dict_1['content'])
        m += 1

其實(shí)就是膊爪,來(lái)兩個(gè)for循環(huán)。第一次確定具體鏈接嚎莉,第二次再提取數(shù)據(jù)米酬。
另外,扇貝里面包含簡(jiǎn)體和繁體解釋?zhuān)蠹铱梢宰孕羞x取趋箩。我現(xiàn)在是用的簡(jiǎn)體zh-CN赃额。
取讀句子的時(shí)候,煉句還有個(gè)麻煩事叫确,它的網(wǎng)頁(yè)跳芳,竟然不是統(tǒng)一的。格式會(huì)有變化竹勉。但總體看下來(lái)飞盆,就是有2種結(jié)構(gòu)

    content_article_2 = re.findall("(\"audio_name.*?), \"audio_urls",Text_article_id)    
    if content_article_2 == []:
        content_article_2 = re.findall("(\"content\".*?\"),",Text_article_id)
        for i in content_article_2:
            if i[len("\"content\": \"")] == "\\":
                 content_article_2.remove(i)
        for i in content_article_2:
            if i[len("\"content\": \"")] == "\\":
                 content_article_2.remove(i)

所以用個(gè)if 判斷一下,第一種情況讀不出的時(shí)候次乓,就用第二種

完整代碼

# -*- coding: utf-8 -*-
"""
Created on Sat May 25 2019

@author: YangYang
"""


import requests
import json
import re
import xlwt

def Login(account,password):
    payloadHeader = {'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
                     'referer': "https://web.shanbay.com/web/account/login/",
                     'content-type': 'application/json'
                     }

    postUrl = 'https://apiv3.shanbay.com/bayuser/login'
    s = requests.Session()  # 為了保存登入信息

    PayloadData  = {
                     'account': account,
                     'code_2fa': "",
                     'password': password     
                    }
    r = s.post(postUrl, data=json.dumps(PayloadData), headers=payloadHeader)
    return s,r

def GetTextWeb(url,s):
    GetUrl = s.get(url)
    return GetUrl.text

# 輸入賬號(hào)密碼登入  
account =input("請(qǐng)輸入你的賬號(hào):")
password = input("請(qǐng)輸入你的密碼:")
s,r = Login(account,password)
print('\n') 
print("賬號(hào)登入成功吓歇!")
# 打開(kāi)Excel
workbook = xlwt.Workbook()  #定義workbook

# 輸入網(wǎng)址
sentence_number = 40  #這是煉句的編號(hào)
book_url = "https://www.shanbay.com/api/v1/sentence/userbook/" + str(sentence_number)
book_phrase_url = "https://www.shanbay.com/api/v1/sentence/book/phrase/"+ str(sentence_number)
book_article_url = "https://www.shanbay.com/api/v1/sentence/book/article/"+ str(sentence_number)

# 獲取煉句書(shū)的標(biāo)題
# 這里有個(gè)奇怪的點(diǎn),有些網(wǎng)頁(yè)能讀出來(lái)檬输,有些不能
# 所以最后,我還是手動(dòng)輸入了(我技術(shù)不行靶偌)
#Text_book = GetTextWeb(book_url,s)
#title = re.findall("(\"title\".*?),",Text_book)
#title = "{"+title[0]+"}"  #轉(zhuǎn)成字典
#title_dict = json.loads(title)
#workbook_title =  title_dict['title']+".xls"  # 給Excel表格命名
workbook_title =  "六級(jí)閱讀短語(yǔ)訓(xùn)練.xls"  # 給Excel表格命名


# 獲取煉句
print('\n') 
print("正在取讀煉句數(shù)據(jù)丧慈,請(qǐng)等待……")
Text_article = GetTextWeb(book_article_url,s)
article_List = re.findall("{\"status.*?}",Text_article)

sheet = workbook.add_sheet('課程內(nèi)容')  #添加sheet
head = [ '內(nèi)容', '解釋']
for h in range(len(head)):
    sheet.write(0, h, head[h])    #把表頭寫(xiě)到Excel里面去
m = 1 #Excel開(kāi)始寫(xiě)入的位置  
n = 1 #Excel開(kāi)始寫(xiě)入的位置  
for article in article_List:
    article_dict = json.loads(article)
    article_id = article_dict['article_id']
    article_id_url = book_article_url+"/"+str(article_id)
    Text_article_id = GetTextWeb(article_id_url,s)
    
    content_article_1 = re.findall(" {\"zh-CN\": {\"content.*?}",Text_article_id)
    for content1 in content_article_1:        
        content1 = content1[len("{\"zh-CN\":")+2:]
        content_dict_1 = json.loads(content1)
        sheet.write(m, 1, content_dict_1['content'])
        m += 1
        
    content_article_2 = re.findall("(\"audio_name.*?), \"audio_urls",Text_article_id)    
    if content_article_2 == []:
        content_article_2 = re.findall("(\"content\".*?\"),",Text_article_id)
        for i in content_article_2:
            if i[len("\"content\": \"")] == "\\":
                 content_article_2.remove(i)
        for i in content_article_2:
            if i[len("\"content\": \"")] == "\\":
                 content_article_2.remove(i)
    for content2 in content_article_2:
        content2 = "{"+content2+"}"  #轉(zhuǎn)成字典
        content_dict_2 = json.loads(content2)
        sheet.write(n, 0, content_dict_2['content'])    
        n += 1
        
    
# 獲取單詞和短語(yǔ)
print('\n') 
print("正在取讀單詞和短語(yǔ)數(shù)據(jù),請(qǐng)等待……")    
Text_phrase = GetTextWeb(book_phrase_url,s)
phrase_List = re.findall("{\"content.*?}",Text_phrase)

sheet = workbook.add_sheet('單詞和短語(yǔ)')  #添加sheet
head = [ '內(nèi)容', '解釋']
for h in range(len(head)):
    sheet.write(0, h, head[h])    #把表頭寫(xiě)到Excel里面去
j = 1 #Excel開(kāi)始寫(xiě)入的位置  

for phrase in phrase_List:
    phrase_dict = json.loads(phrase)
    sheet.write(j, 0, phrase_dict['content'])
    sheet.write(j, 1, phrase_dict['definition'])
    j += 1

  
workbook.save(workbook_title)
print('\n') 
print('寫(xiě)入excel成功')
print("文件位置:和代碼在同一個(gè)文件夾")
print('\n') 
input("煉句取讀完畢主卫,點(diǎn)擊回車(chē)退出")


最后補(bǔ)充:爬取個(gè)人單詞書(shū)

方式和煉句是完全一致的逃默,就是網(wǎng)址不同

網(wǎng)址后面有一個(gè)&_=1559700584497,這個(gè)是個(gè)時(shí)間戳(寫(xiě)代碼的時(shí)候可以不加簇搅,也能獲取數(shù)據(jù))

url = 'https://www.shanbay.com/api/v1/bdc/library/today/?page=1'
word = s.get(url)  # 這里換成get了完域,剛剛是s.post
print(word.text)

這時(shí)候就能看到對(duì)應(yīng)單詞的拼寫(xiě)、發(fā)音瘩将、解釋等等
比如anecdotal吟税,它的數(shù)據(jù),和網(wǎng)頁(yè)顯示一致

同樣姿现,系統(tǒng)儲(chǔ)存的時(shí)候肠仪,都是編碼\u02cc\這種,轉(zhuǎn)成文字就好啦~
你可以點(diǎn)Preview备典,一個(gè)單詞异旧,里面有發(fā)音、中英文解釋提佣、例句等等
你需要哪些吮蛹,就獲取哪些

具體數(shù)據(jù)清洗荤崇,這里不廢話了,之前操作都講過(guò)啦~

附:參考網(wǎng)頁(yè)

爬蟲(chóng)(抓取靜態(tài)頁(yè)面和動(dòng)態(tài)頁(yè)面的區(qū)別潮针,get請(qǐng)求和post請(qǐng)求的區(qū)別):https://blog.csdn.net/Spencer_q/article/details/82631154
扇貝自動(dòng)打卡Python腳本(Python3)
http://www.reibang.com/p/284499d5e8b5
如何查看接口术荤?
https://blog.csdn.net/meiceatcsdn/article/details/79999439
python爬蟲(chóng)如何POST request payload形式的請(qǐng)求
https://blog.csdn.net/zwq912318834/article/details/79930423

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市然低,隨后出現(xiàn)的幾起案子喜每,更是在濱河造成了極大的恐慌,老刑警劉巖雳攘,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件带兜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡吨灭,警方通過(guò)查閱死者的電腦和手機(jī)刚照,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)喧兄,“玉大人无畔,你說(shuō)我怎么就攤上這事》驮” “怎么了浑彰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)拯辙。 經(jīng)常有香客問(wèn)我郭变,道長(zhǎng),這世上最難降的妖魔是什么涯保? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任诉濒,我火速辦了婚禮,結(jié)果婚禮上夕春,老公的妹妹穿的比我還像新娘未荒。我一直安慰自己,他們只是感情好及志,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布片排。 她就那樣靜靜地躺著,像睡著了一般速侈。 火紅的嫁衣襯著肌膚如雪划纽。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天锌畸,我揣著相機(jī)與錄音勇劣,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛比默,可吹牛的內(nèi)容都是我干的幻捏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼命咐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼篡九!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起醋奠,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤榛臼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后窜司,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體沛善,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年塞祈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了金刁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡议薪,死狀恐怖尤蛮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斯议,我是刑警寧澤产捞,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站哼御,受9級(jí)特大地震影響坯临,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜艇搀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一尿扯、第九天 我趴在偏房一處隱蔽的房頂上張望求晶。 院中可真熱鬧焰雕,春花似錦、人聲如沸芳杏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)爵赵。三九已至吝秕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間空幻,已是汗流浹背烁峭。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人约郁。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓缩挑,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鬓梅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子供置,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353