手把手系列:用Python3+PyQt5做一個(gè)有界面的小爬蟲(三)


升級(jí)裝備棺榔,讓你的小爬蟲變得更能干

在上一篇文章中我們講到了如何用requests對(duì)網(wǎng)頁進(jìn)行GET和POST請(qǐng)求询吴,以及用BeautifulSoup對(duì)請(qǐng)求到的頁面進(jìn)行分析。但是單單這樣哨苛,小爬蟲只能對(duì)單一的頁面進(jìn)行爬取己莺,還并不能完全解放我們的人力,只能算是個(gè)半自動(dòng)的爬蟲尖飞,那么這篇文章中症副,我們要給這只小爬蟲再升級(jí)幾件厲害的裝備,讓它變得更能干政基!

任務(wù)目標(biāo)

首先贞铣,我們面前有一份長長的Excel表格,里面提供了文章的案例編號(hào)沮明,需要爬蟲根據(jù)這份表格里面的案例編號(hào)辕坝,來進(jìn)行相對(duì)應(yīng)文章的爬取。其次荐健,我們還需要對(duì)每篇文章爬取的內(nèi)容做保存酱畅,不然關(guān)掉IDE后琳袄,數(shù)據(jù)就全部丟失了。

根據(jù)這份需求纺酸,我們需要給這只小爬蟲裝備上2件裝備

  • 對(duì)Excel文件的操作
  • 對(duì)文件進(jìn)行讀取和寫入操作
裝備一:對(duì)Excel文件的讀取操作

第一步還是需要邀請(qǐng)pip來配合窖逗,通過pip來自動(dòng)安裝xlrd模塊。

pip install xlrd

這兒解釋下餐蔬,xlrd模塊是對(duì)Excel進(jìn)行讀取操作的滑负,寫入操作需要另外一個(gè)叫xlwt的模塊來支持。這兒我們只需要讀取操作用含,所以只要引用xlrd模塊就行了。

這份是我們需要導(dǎo)入讀取的Excel文件帮匾,我們要讀取里面第二列的全部案例編號(hào)啄骇,并取出來。

import xlrd #導(dǎo)入excel 模塊

# 打開EXCEL文檔獲取內(nèi)容
def read_excel():
   #文件位置
    ExcelFile=xlrd.open_workbook(r'C:\Users\Saber\Desktop\案例編號(hào)清單.xlsx')
    #獲取目標(biāo)EXCEL文件sheet名
    sheet = ExcelFile.sheet_by_name('Sheet1')
    print('該Excel文檔共有' + str(sheet.nrows-1) + '篇文章需要爬取\n')
    #獲取第二列的值
    rows = sheet.col_values(1)
    #刪除第一行的標(biāo)題
    rows.pop(0)
     
    # 清洗數(shù)據(jù)瘟斜,把空格的都排除掉
    new_excel = []
    for a in rows:
        a = a.replace(u'\xa0', u'').replace(u' ', u'')
        new_excel.append(a)
    print('獲取案例編號(hào)成功\n')
    return new_excel

因?yàn)镋xcel里會(huì)有空格缸夹,所以獲得原始數(shù)據(jù)后要再把空格都排除掉。\xa0 是不間斷空白符螺句。執(zhí)行一下虽惭,成功獲取到我們希望得到的數(shù)據(jù)。

裝備二:對(duì)文件進(jìn)行讀取和寫入操作

完成了Excel文件的讀取蛇尚,我們還要將數(shù)據(jù)進(jìn)行輸出芽唇。這個(gè)需要引用一個(gè)OS模塊,這個(gè)OS模塊包含在Python的標(biāo)準(zhǔn)庫中取劫,不需要額外的安裝匆笤。這兒我們還是拿剛才的導(dǎo)入Excel表數(shù)據(jù)做例子,將Excel表中的信息輸出到文件中并保存起來谱邪。

def read_excel():
    ## ......上面代碼省略......##
    print('獲取案例編號(hào)成功\n')

    # 以寫的方式打開ExcelData.txt
    pageFile = open('ExcelData.txt','a+')
    # 寫入內(nèi)容
    pageFile.write('該EXCEL文檔共有' + str(sheet.nrows-1) + '篇文章需要爬取\n')
    # 打開了記得還要關(guān)閉
    pageFile.close()

    return new_excel

read_excel()末尾加入這么三行代碼炮捧。即可以完成文件的打開,內(nèi)容寫入惦银,文件關(guān)閉的操作咆课,非常簡單。效果如下圖所示扯俱。

這里要講解一下open()這個(gè)方法书蚪。這個(gè)方法里面需要傳入2個(gè)參數(shù)open("文件名","打開方式")蘸吓,其中打開方式中有很多種善炫。我在這兒選擇了a+的方式,因?yàn)樗麜?huì)判斷文件是否存在库继,不存在則新建箩艺,存在則追加數(shù)據(jù)窜醉,非常適合這次的使用場景。

r 打開只讀文件艺谆,該文件必須存在榨惰。
r+ 具有讀寫屬性,從文件頭開始寫静汤,保留原文件中沒有被覆蓋的內(nèi)容琅催,文件必須存在。
w 打開只寫文件虫给,若文件存在則文件長度清為0藤抡,即該文件內(nèi)容會(huì)消失。若文件不存在則建立該文件抹估。
w+ 具有讀寫屬性缠黍,寫的時(shí)候如果文件存在,會(huì)被清空药蜻,從頭開始寫瓷式,如文件不存在則創(chuàng)建該文件。
a 以附加的方式打開只寫文件语泽。若文件不存在贸典,則會(huì)建立該文件,如果文件存在踱卵,寫入的數(shù)據(jù)會(huì)被加到文件尾廊驼,即文件原先的內(nèi)容會(huì)被保留。
a+ 以附加方式打開可讀寫的文件惋砂。若文件不存在蔬充,則會(huì)建立該文件,如果文件存在班利,寫入的數(shù)據(jù)會(huì)被加到文件尾后饥漫,即文件原先的內(nèi)容會(huì)被保留。

w+與r+區(qū)別:r+:可讀可寫罗标,若文件不存在庸队,報(bào)錯(cuò);w+: 可讀可寫闯割,若文件不存在彻消,創(chuàng)建
r+與a+區(qū)別:r+,可讀寫宙拉,文件必須文件宾尚,從文件開頭開始寫;a+,可讀寫煌贴,文件存在則在文件末尾追加寫御板;文件不存在則創(chuàng)建文件

更詳細(xì)的講解可以參考這篇文章:python文件操作

到此為止,小爬蟲的兩個(gè)新裝備都介紹完畢啦牛郑,我們要對(duì)爬蟲改造下怠肋,讓他能一鍵自動(dòng)按照指定Excel表中的案例編號(hào)進(jìn)行自動(dòng)爬取,并輸出保存爬取到的內(nèi)存淹朋。

改造小爬蟲

在上面我們獲取了全部需要爬取的案例編號(hào)后笙各,進(jìn)入網(wǎng)站發(fā)現(xiàn),每篇文章的caseId編號(hào)并不是使用這個(gè)案例編號(hào)的础芍,需要通過案例編號(hào)搜索杈抢,來獲取每篇文章的caseId,然后才能根據(jù)這個(gè)caseId來對(duì)文章和文章的評(píng)論進(jìn)行訪問仑性。那么春感,我們要先通過這個(gè)案例編號(hào)來獲取文章的caseId。

輸入案例編號(hào)虏缸,點(diǎn)擊搜索后會(huì)出現(xiàn)相對(duì)應(yīng)的文章。

然后對(duì)文章標(biāo)題進(jìn)行審查元素嫩实,可以看到這是個(gè)超鏈接刽辙,文章caseId就在這個(gè)超鏈接中http://xxx.action?caseId=287270。但是經(jīng)過摸索甲献,發(fā)現(xiàn)前面的那個(gè)input標(biāo)簽的value也帶有這個(gè)caseId宰缤,而且這個(gè)input標(biāo)簽全文只有2個(gè),比起a標(biāo)簽來更方便解析晃洒,于是我決定取這個(gè)input標(biāo)簽中value值慨灭。

通過抓取請(qǐng)求,分析球及,這是一個(gè)POST請(qǐng)求氧骤。Form參數(shù)一共有6個(gè),需要填寫的有3個(gè)吃引,其中核心參數(shù)就是這個(gè)caseSn筹陵。

# 爬取文章鏈接
class BeautifulGetUrl():
    def __init__(self,sn,header):  #類的初始化操作
        self.article_caseId = []  #爬取到的caseId都放到這個(gè)list中,實(shí)例化這個(gè)類后可以隨時(shí)調(diào)用
        self.headers = header  #給請(qǐng)求指定一個(gè)請(qǐng)求頭來模擬chrome瀏覽器
        self.web_url = 'http://net.chinamobile.com/cmccnkms-case/web/casemajor/caseList.action'  #要訪問的網(wǎng)頁地址
        self.caseSn = sn
    def get_caseId(self):
        print('開始文章CaseID獲取的POST請(qǐng)求')
        for x in self.caseSn:
            web_data = {
                'pageNum':'',
                'majorName':'無線',
                'orderType':'ZRequestTime',
                'caseTitle':'',
                'caseSn':x,
                'caseAuthor':''
            }
            r = requests.post(self.web_url,data=web_data, headers=self.headers)
            find_tag = BeautifulSoup(r.text, 'lxml').find_all('input',type='checkbox')
            #判斷是否可以搜索到文章,搜不到就把內(nèi)容置為-1
            if len(find_tag) == 1:  
                self.article_caseId.append('-1') 
                print(x)
                print('找不到該篇文章')
            else:
                self.article_caseId.append(find_tag[1]['value']) #獲取標(biāo)簽的value值
                print(x)
                print(find_tag[1]['value'])

來解讀一下這段代碼镊尺,這兒因?yàn)檫@幾個(gè)請(qǐng)求的header部分都是一樣的朦佩,所以精簡代碼,把header作為參數(shù)來傳入庐氮,同時(shí)也傳入之前獲取到的案例編號(hào)列表语稠。

通過for循環(huán),將caseSn一個(gè)一個(gè)的傳入弄砍,作為form的參數(shù)仙畦,然后對(duì)地址進(jìn)行post請(qǐng)求输涕。在BeautifulSoup中對(duì)標(biāo)簽為input,類型為checkbox進(jìn)行解析议泵,如果能搜索到這篇文章占贫,就會(huì)有兩個(gè)tag,取第二tag的value值就是我們所需要的caseId先口,然后將這個(gè)追加到之前定義的article_caseId中型奥。

這兒增加一個(gè)判斷是因?yàn)椋绻撈恼抡趯徍嘶蛘邔徍藳]有通過的話碉京,是搜索不到的厢汹。搜索不到的話,解析到checkbox的tag只有一個(gè)谐宙,我們默認(rèn)取第二個(gè)tag程序就會(huì)報(bào)錯(cuò)烫葬,這個(gè)是需要避免的,所以增加了一個(gè)判斷凡蜻。如果解析出來的tag只有一個(gè)搭综,那么就說明找不到該篇文章,加入一個(gè)-1的標(biāo)識(shí)符划栓,如果不加的話兑巾,那么article_caseId的下標(biāo)就和之前Excel獲取到的案例編號(hào)下標(biāo)對(duì)不上號(hào)了,必須要加上去忠荞,不能略過蒋歌。

再來改造下最后類的實(shí)例化操作
附上完整的代碼塊

import xlrd #導(dǎo)入excel 模塊
import os  #導(dǎo)入os模塊
import requests #導(dǎo)入requests 模塊
from bs4 import BeautifulSoup  #導(dǎo)入BeautifulSoup 模塊

# 打開EXCEL文檔獲取內(nèi)容
def read_excel():
    ......

# 爬取文章caseId
class BeautifulGetCaseId():
    def __init__(self,sn,header):  #類的初始化操作
        ......
    def get_caseId(self):
        ......

# 爬取文章案例編號(hào)和當(dāng)前周期有效閱讀數(shù)
class BeautifulGetCaseSNandReadNum():
    def __init__(self,i,a,header):  #類的初始化操作
        ......
    def get_data(self):
        ......

# 爬取具體信息
class BeautifulGetData():
    def __init__(self,i,caseId,caseSN,header):  #類的初始化操作
        ......
    def get_data(self):
        ......

#給請(qǐng)求指定一個(gè)請(qǐng)求頭來模擬chrome瀏覽器
header = {
    ...... 
}

new_excel = read_excel() #從excel中獲取需要的信息
print('獲取案例編號(hào)成功')

beauty = BeautifulGetCaseId(new_excel,header)  #創(chuàng)建類的實(shí)例,根據(jù)Excel爬取文章caseId
beauty.get_caseId  #執(zhí)行類中的方法
print('爬取文章鏈接成功')

for i,caseId in enumerate(beauty.article_caseId):
    if caseId == '-1':
        pageFile = open('ExcelData.txt','a+')  #以寫的方式打開ExcelData.txt
        pageFile.write('這是爬取的第' + str(i+1) + '篇文章\n案例編號(hào):' + new_excel[i] + '\n\n該案例編號(hào)搜索不到相對(duì)應(yīng)的文章\n')
        pageFile.close()#開了記得關(guān)
        continue
    getCaseSN = BeautifulGetCaseSNandReadNum(i,caseId,header)  #創(chuàng)建類的實(shí)例委煤,根據(jù)caseId爬取文章基礎(chǔ)信息
    getData = BeautifulGetData(i,caseId,new_excel[i],header)  #創(chuàng)建類的實(shí)例堂油,根據(jù)caseId爬取文章評(píng)論信息
    getCaseSN.get_data()
    getData.get_data()

print('爬取具體信息成功')

非常完美,爬取成功碧绞,忍不住都想夸一下能干的自己府框。

后記

截止到現(xiàn)在,一個(gè)能解放人力的小爬蟲誕生了讥邻。但是現(xiàn)在還有個(gè)問題寓免,這個(gè)爬蟲并不是自己使用,而是要交給需要的人來操作使用的计维,交付的人可不會(huì)這些代碼(但是他們?nèi)绻戳宋疫@個(gè)手把手系列袜香,我相信他們也一定能熟練的調(diào)教這只小爬蟲),虛要改一些參數(shù)的話鲫惶,就會(huì)變得很麻煩蜈首。那么我們就需要給這只小爬蟲做一套衣服,讓他成為一只界面友好型的小爬蟲,然后安安心心的交給他人來使用欢策。在下篇文章中我就來講一講Python的圖形界面吆寨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市踩寇,隨后出現(xiàn)的幾起案子啄清,更是在濱河造成了極大的恐慌,老刑警劉巖俺孙,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辣卒,死亡現(xiàn)場離奇詭異,居然都是意外死亡睛榄,警方通過查閱死者的電腦和手機(jī)荣茫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來场靴,“玉大人啡莉,你說我怎么就攤上這事≈及” “怎么了咧欣?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長轨帜。 經(jīng)常有香客問我魄咕,道長,這世上最難降的妖魔是什么阵谚? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮烟具,結(jié)果婚禮上梢什,老公的妹妹穿的比我還像新娘。我一直安慰自己朝聋,他們只是感情好嗡午,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冀痕,像睡著了一般荔睹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上言蛇,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天僻他,我揣著相機(jī)與錄音,去河邊找鬼腊尚。 笑死吨拗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劝篷,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼哨鸭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了娇妓?” 一聲冷哼從身側(cè)響起像鸡,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哈恰,沒想到半個(gè)月后只估,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蕊蝗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年仅乓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓬戚。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡夸楣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出子漩,到底是詐尸還是另有隱情豫喧,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布幢泼,位于F島的核電站紧显,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏缕棵。R本人自食惡果不足惜孵班,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望招驴。 院中可真熱鬧篙程,春花似錦、人聲如沸别厘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽触趴。三九已至氮发,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冗懦,已是汗流浹背爽冕。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留披蕉,地道東北人扇售。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓前塔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親承冰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子华弓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容