Python從放棄到入門(mén):公眾號(hào)歷史文章爬取為例談快速學(xué)習(xí)技能

這篇文章不談江流所專研的營(yíng)銷與運(yùn)營(yíng)撒蟀,而聊一聊技能學(xué)習(xí)之路忆肾,聊一聊Python這門(mén)最簡(jiǎn)單的編程語(yǔ)言該如何學(xué)習(xí)夺衍,我完成的第一個(gè)Python項(xiàng)目捐迫,將任意公眾號(hào)的所有歷史文章導(dǎo)出成PDF電子書(shū)。

或許我這個(gè)Python初學(xué)者的學(xué)習(xí)路徑能給你帶來(lái)啟發(fā)籽腕,或許你產(chǎn)生了要學(xué)一門(mén)新技術(shù)的沖動(dòng)嗡呼。

文末附送了學(xué)習(xí)資源通道。

學(xué)習(xí)python兩度放棄最終有所成

我想要學(xué)python五年了皇耗,三度捧起python入門(mén)書(shū)決定開(kāi)啟學(xué)習(xí)南窗,到第三次才算上道了。

第一次死于安裝軟件環(huán)境郎楼,安裝碰了太多壁万伤,面對(duì)各種困難無(wú)從解決而擱置。所以傳說(shuō)三分之一python學(xué)習(xí)者死于安裝軟件呜袁,此言不虛敌买。

第二次死于一直找不到成就感。從學(xué)習(xí)python到能夠正經(jīng)用python干些有意義的事情阶界,太費(fèi)時(shí)虹钮,于是擱置了。這實(shí)際上是學(xué)習(xí)方法不對(duì)荐操,花費(fèi)太多時(shí)間學(xué)習(xí)知識(shí)點(diǎn)芜抒,而不是盡早通過(guò)解決實(shí)際問(wèn)題學(xué)習(xí)。

第三次托启,經(jīng)過(guò)一個(gè)星期的死磕宅倒,終于完成了爬取任意公眾號(hào)歷史文章并生成PDF文集這件事。獲得了成就感屯耸,也在死磕的過(guò)程中總算入門(mén)了python拐迁。

Python很火,誰(shuí)都可以學(xué)

想要學(xué)一項(xiàng)技能與學(xué)成一項(xiàng)技能之間往往有些差距疗绣,我們往往想得多线召,而堅(jiān)持的少。所以堅(jiān)持了一件事情多矮,就值得寫(xiě)文章紀(jì)念一下缓淹,并給他人以啟迪哈打。

python火了幾年了,有詩(shī)為證讯壶,“人生苦短料仗,快學(xué)python”。

python幾乎是各種編程語(yǔ)言里最簡(jiǎn)單易學(xué)的語(yǔ)言伏蚊,python的應(yīng)用范圍很廣立轧,爬蟲(chóng),數(shù)據(jù)分析躏吊,網(wǎng)站開(kāi)發(fā)氛改,自動(dòng)化辦公,機(jī)器學(xué)習(xí)比伏,云計(jì)算胜卤,python有大量的庫(kù),意味著我們用python編程可以充分利用前人的勞動(dòng)成果赁项,對(duì)程序進(jìn)行改編瑰艘,或者運(yùn)用前人編好的功能模塊,進(jìn)行重新組合肤舞,來(lái)創(chuàng)造達(dá)你的新程序。結(jié)果是你用C++可能要寫(xiě)1000行代碼均蜜,用Python寫(xiě)50行代碼就干了同樣的事情李剖。

傳說(shuō)有些娛樂(lè)圈明星在學(xué)python,雖然我目前也沒(méi)有看到她們的學(xué)習(xí)成果囤耳,可能有的放棄了篙顺,可能有的已經(jīng)在悶聲發(fā)大財(cái)。

知名商人潘石屹充择,賣了自己的地產(chǎn)德玫,也專心學(xué)python去了,他已經(jīng)堅(jiān)持微博打卡學(xué)python半年多了椎麦,每條微博都會(huì)提及輔導(dǎo)自己Python的培訓(xùn)機(jī)構(gòu)宰僧。我們也不知道他是單純的行為藝術(shù)癖好呢,還是就是想體會(huì)中學(xué)生刷題的樂(lè)趣呢观挎,還是是因?yàn)楦男凶隽四撑嘤?xùn)機(jī)構(gòu)的幕后股東為其站臺(tái)琴儿。

我們學(xué)python可沒(méi)刷半年題的耐心,追求的就是能快速豐富自己的能力嘁捷,創(chuàng)造更多可能性造成。

學(xué)習(xí)Python的最短準(zhǔn)備路徑

學(xué)習(xí)Python第一步:裝合適的軟件環(huán)境,買(mǎi)一本合適的入門(mén)書(shū)

我最開(kāi)始雄嚣,看到各種討論安裝哪個(gè)python版本晒屎,安裝什么樣的python環(huán)境,怎么安裝需要用到的各種包,觀點(diǎn)不一鼓鲁,而且容易安裝失敗蕴轨。這個(gè)過(guò)程讓很多人絕望。

趟過(guò)各種坑后坐桩,推薦初學(xué)者無(wú)腦按以下步驟來(lái):

下載安裝python3.7版本尺棋。其他python3的版本應(yīng)該也可以。

下載pycharm(感謝北京的張祥幫忙下載安裝)绵跷,我的是JetBrains PyCharm 2018.3.2版本膘螟。

搜索下pycharm激活碼(激活碼經(jīng)常失效,后臺(tái)可告訴你怎么找激活碼碾局,我試了挺多激活碼都無(wú)效的)

買(mǎi)本《Python編程快速上手:讓繁瑣工作自動(dòng)化(第2版)》荆残,這本書(shū)豆瓣評(píng)分9.0分,其實(shí)作者在他的個(gè)人網(wǎng)站發(fā)布了該書(shū)1.0版的英文版净当,書(shū)中有網(wǎng)站鏈接内斯,用chrome瀏覽器的自帶翻譯也能流暢閱讀。但我總覺(jué)得學(xué)習(xí)一項(xiàng)技能要買(mǎi)本書(shū)創(chuàng)造點(diǎn)儀式感像啼。

有很多人推薦廖雪峰的Python入門(mén)教程俘闯,網(wǎng)上可以搜到網(wǎng)站,但我看了下目錄忽冻,總覺(jué)得學(xué)習(xí)過(guò)程過(guò)于漫長(zhǎng)真朗,離上手項(xiàng)目太遙遠(yuǎn),很容易促使新手放棄僧诚。

而《Python編程快速上手》這本書(shū)遮婶,只需要看基礎(chǔ)部分那110頁(yè),然后看自動(dòng)化任務(wù)部分的兩個(gè)章節(jié)湖笨,比如對(duì)我要做的爬蟲(chóng)項(xiàng)目有用的是讀寫(xiě)文件這個(gè)章節(jié)和從web抓取信息這個(gè)章節(jié)旗扑。其他內(nèi)容則是在項(xiàng)目實(shí)踐過(guò)程中,遇到了問(wèn)題慈省,再回頭查找書(shū)中的相關(guān)內(nèi)容補(bǔ)充臀防。

這是我目前認(rèn)為的自學(xué)Python的最短路徑。

安裝各種第三方包

Python的妙處是有大量的第三方開(kāi)發(fā)的包辫呻,用于各種功能清钥,你在某個(gè)具體項(xiàng)目中,可能會(huì)用到其中的幾個(gè)包放闺,這些包就節(jié)省了你大量的工作量祟昭。

進(jìn)入PyCharm,進(jìn)入File-Settings-Project-Project Interpreter怖侦,點(diǎn)擊右側(cè)的“+”號(hào)篡悟,就可以搜索你需要的包谜叹,點(diǎn)擊Install安裝了。

image

有時(shí)會(huì)安裝失敗搬葬,但成功率高于其他方式荷腊。如果安裝失敗,你可以考慮1急凰、等網(wǎng)絡(luò)狀況好了再試試女仰;2、打開(kāi)VPN再下載抡锈;3疾忍、在Pycharm界面底部選擇Terminal,然后輸入pip install +要安裝的包床三。

image

上GITHUB找相關(guān)項(xiàng)目代碼

我們初學(xué)者一罩,最好的方式是找前人的項(xiàng)目代碼研究。通過(guò)改編借鑒別人的代碼或者思路撇簿,來(lái)實(shí)現(xiàn)自己的目的聂渊。

我遵循行業(yè)規(guī)矩,上GITHUB網(wǎng)站(https://github.com/)搜索相關(guān)項(xiàng)目四瘫,GITHUB的用法還需要學(xué)習(xí)下汉嗽,B站上有一些視頻教程。我遵循規(guī)矩在GITHUB注冊(cè)了賬號(hào)找蜜,然后安裝了GITHUB Desktop(就是桌面客戶端)诊胞。

這樣,我就可以

1锹杈、登陸GITHUB網(wǎng)站搜索相關(guān)項(xiàng)目。

2迈着、點(diǎn)擊搜索結(jié)果查看可能相關(guān)的項(xiàng)目竭望。

3、點(diǎn)擊綠色按鈕Clone or Download裕菠,再點(diǎn)擊Open in Desktop咬清,將項(xiàng)目保存到本地。

4奴潘、在本地保存項(xiàng)目的文件夾里旧烧,打開(kāi)py后綴的文件,查看和修改項(xiàng)目代碼画髓。

這里GITHUB Desktop的作用似乎可有可無(wú)掘剪,但是當(dāng)我們跨過(guò)了初學(xué)者的階段,才會(huì)發(fā)現(xiàn)它的作用奈虾,作用是方便保管項(xiàng)目文件夺谁,并顯示項(xiàng)目更新廉赔,并同步到云上,以便其他人能夠同步改進(jìn)匾鸥。

GITHUB的項(xiàng)目下載速度很慢蜡塌,可以試試打開(kāi)VPN加速。有人推薦國(guó)內(nèi)版的GITHUB“碼云”勿负,說(shuō)下載速度更快馏艾,說(shuō)能把GITHUB上的代碼同步到碼云然后下載,我注冊(cè)了奴愉,但還沒(méi)正式用琅摩。

image

梳理項(xiàng)目邏輯

《Python編程快速上手》這本書(shū)的一個(gè)妙處在于,教給了我們簡(jiǎn)潔的工作方法躁劣。指導(dǎo)我們?cè)陂_(kāi)始項(xiàng)目前先要梳理這個(gè)程序需要依次實(shí)現(xiàn)的動(dòng)作迫吐。

以我完成的爬取公眾號(hào)歷史文章這個(gè)項(xiàng)目為例。

第一步:我給自己樹(shù)立了一個(gè)任務(wù)账忘,就是要把某一個(gè)微信公眾號(hào)的歷史文章都整理到一個(gè)pdf文檔里志膀。方便我存檔信息。

第二步:分解步驟鳖擒,我認(rèn)為要完成我這個(gè)任務(wù)溉浙,我需要做三件事。

1蒋荚、找到獲得公眾號(hào)歷史文章url的方式戳稽。

2、抓去到這個(gè)公眾號(hào)所有歷史文章的url期升,并保存到一個(gè)文件中惊奇。

3、讀取每個(gè)文章的url鏈接里的文章內(nèi)容播赁,生成pdf文件颂郎。

通過(guò)看書(shū),我已經(jīng)知道了第三步用pdfkit這個(gè)包就可以完成容为,將url等數(shù)據(jù)保存到csv文件里也可以完成乓序。所以任務(wù)變成了,如何抓取到一個(gè)公眾號(hào)所有歷史文章的url鏈接了坎背。

第三步:去GITHUB里找相關(guān)項(xiàng)目替劈。

由于微信的挺強(qiáng)的反爬蟲(chóng)能力,很多相關(guān)項(xiàng)目都已經(jīng)不能順利運(yùn)行得滤,我們需要尋找相似的項(xiàng)目陨献,分析其邏輯是否可行。

我找到一個(gè)項(xiàng)目懂更,里面討論了獲取url的幾種方法湿故。根據(jù)爬蟲(chóng)所見(jiàn)即所得的原則阿趁,你在前端能看到的東西,就一定能用爬蟲(chóng)爬到坛猪。

這里就要插入一個(gè)知識(shí)點(diǎn)了脖阵。在chrome瀏覽器某個(gè)頁(yè)面,按F12鍵墅茉,可以打開(kāi)瀏覽器的開(kāi)發(fā)者模式命黔,可以查看這個(gè)網(wǎng)頁(yè)的源代碼。只要你在某個(gè)頁(yè)面的源代碼中可以找到url就斤,這個(gè) url就可以被爬到悍募。

有一種方法是微信PC端查看公眾號(hào)的歷史文集時(shí)可以看到url,但以前我看一個(gè)爬蟲(chóng)教程教這種方法時(shí)洋机,在手機(jī)與電腦連接同一個(gè)wifi的過(guò)程中坠宴,遇到了難處,可能是手機(jī)的問(wèn)題绷旗,所以這次我就沒(méi)敢嘗試這種方法喜鼓。

有一種方法是通過(guò)個(gè)人微信號(hào)登陸后臺(tái),搜索任意公眾號(hào)衔肢,可以看到這個(gè)公眾號(hào)發(fā)的文章庄岖,可以查到文章的永久鏈接。于是我決定使用這種方法角骤。

網(wǎng)上看到很多文章的方法是通過(guò)搜狗搜索引擎搜索公眾號(hào)文章隅忿,進(jìn)行篩選,然而問(wèn)題是搜狗只顯示100頁(yè)搜索結(jié)果邦尊,并且不一定能夠做到搜索精確背桐,所以幾乎不可能做到下載一個(gè) 公眾號(hào)的所有歷史文章,故排除這一思路蝉揍。

在GITHUB上下載了運(yùn)用個(gè)人微信公眾號(hào)這個(gè)方法的python代碼牢撼,run了一下失敗了。然后就開(kāi)始讀代碼疑苫,想弄明白這個(gè)代碼的邏輯是什么樣子的,在哪些問(wèn)題上需要修改纷责。

發(fā)現(xiàn)問(wèn)題捍掺,解決問(wèn)題

有了現(xiàn)成的代碼后,我的任務(wù)進(jìn)一步細(xì)化再膳。在現(xiàn)有代碼的基礎(chǔ)上挺勿,梳理邏輯,尋找出錯(cuò)的地方喂柒,尋找已經(jīng)過(guò)時(shí)的地方不瓶。我只需要解決現(xiàn)有代碼中出現(xiàn)的bug禾嫉,一個(gè)個(gè)解決掉,就應(yīng)該能夠爬到url蚊丐。

我發(fā)現(xiàn)這個(gè)程序用到的是selenium包熙参,于是從頭去了解了selenium這個(gè)包的特點(diǎn),工作原理麦备,入門(mén)書(shū)里的相關(guān)章節(jié)孽椰。

selenium是一種Python可以用的爬蟲(chóng)工具,特點(diǎn)是模擬人操作電腦完成各種動(dòng)作凛篙,比如自動(dòng)打開(kāi)某些頁(yè)面黍匾,進(jìn)行翻頁(yè),點(diǎn)擊呛梆,動(dòng)作等锐涯,比如解讀某個(gè)頁(yè)面的源代碼,提取出url等內(nèi)容填物。優(yōu)點(diǎn)是你只要人工能完成的動(dòng)作就能用selenium完成纹腌,缺點(diǎn)是速度慢,容易被反爬蟲(chóng)檢測(cè)到融痛。

經(jīng)過(guò)閱讀代碼壶笼,我發(fā)現(xiàn)這個(gè)程序的邏輯是這樣的:

1、通過(guò)import工具引入需要用到的包雁刷。

2覆劈、通過(guò)def語(yǔ)句,定義一些需要用到的動(dòng)作沛励。

3责语、按順序排列這個(gè)程序依次需要執(zhí)行的動(dòng)作。

4目派、通過(guò)for循環(huán)實(shí)現(xiàn)依次完成抓取url的重復(fù)性動(dòng)作坤候。

5、將抓取到的url保存到一個(gè)數(shù)組企蹭,再保存到一個(gè)數(shù)據(jù)庫(kù)中白筹。

由于我還沒(méi)有學(xué)習(xí)python和數(shù)據(jù)庫(kù)是如何配合的,我想將數(shù)據(jù)保存到csv文件中谅摄,應(yīng)該也可以被調(diào)用徒河,并且csv文件我可以直接打開(kāi)查看效果。

于是我將步驟5的代碼從保存到數(shù)據(jù)庫(kù)改為保存到csv文件送漠。為了怕我反悔顽照,我在代碼前添加#號(hào)讓某些代碼不被執(zhí)行。

以下是原代碼中保存到數(shù)據(jù)庫(kù)的代碼闽寡,被我棄用代兵。

<pre>with open('data2.pickle', 'wb') as f:
pickle.dump(data, f)

讀取

with open('data.pickle', 'rb') as f:
b = pickle.load(f)</pre>

我改為保存到csv文件的代碼尼酿。

<pre>outputFile = open('outputurl.csv','w',newline='')
outputWriter = csv.writer(outputFile)
outputWriter.writerow(url_title_lst)
outputFile.close()</pre>

這段代碼確實(shí)實(shí)現(xiàn)了將數(shù)據(jù)保存到csv文件,但是格式很有問(wèn)題植影,之后放我后來(lái)發(fā)現(xiàn)問(wèn)題并更改的代碼裳擎。

解決bug1:

原代碼作者有提醒,為了使用selenium何乎,需要使用與chrome瀏覽器相對(duì)應(yīng)的chrome driver句惯,為了滿足這個(gè)要求,也花了我不少功夫支救。最后百度搜索了一番抢野,終于找到了適配的chrome driver,成功的標(biāo)志是運(yùn)行程序時(shí)各墨,chrome瀏覽器被自動(dòng)啟動(dòng)了指孤。搜索關(guān)鍵詞“selenium chrome driver”

看到chrome瀏覽器自動(dòng)啟動(dòng)的時(shí)候,內(nèi)心開(kāi)心贬堵,因?yàn)檫@個(gè)程序我已經(jīng)跑通了第一步恃轩。

解決bug2:

chrome瀏覽器自動(dòng)啟動(dòng),并打開(kāi)了微信公眾平臺(tái)的登陸頁(yè)黎做,然而程序停了叉跛。

于是我看代碼尋找原因。

<pre>def login(username, password):
#打開(kāi)微信公眾號(hào)登錄頁(yè)面
driver.get('https://mp.weixin.qq.com/')
driver.maximize_window()
time.sleep(3)
# 自動(dòng)填充帳號(hào)密碼
driver.find_element_by_xpath("http://[@id="header"]/div[2]/div/div/form/div[1]/div[1]/div/span/input").clear()
driver.find_element_by_xpath("http://
[@id="header"]/div[2]/div/div/form/div[1]/div[1]/div/span/input").send_keys(username)
driver.find_element_by_xpath("http://[@id="header"]/div[2]/div/div/form/div[1]/div[2]/div/span/input").clear()
driver.find_element_by_xpath("http://
[@id="header"]/div[2]/div/div/form/div[1]/div[2]/div/span/input").send_keys(password)
time.sleep(1)
#自動(dòng)點(diǎn)擊登錄按鈕進(jìn)行登錄
driver.find_element_by_xpath("http://*[@id="header"]/div[2]/div/div/form/div[4]/a").click()
# 拿手機(jī)掃二維碼蒸殿!
time.sleep(15)</pre>

猜想是在自動(dòng)填充的過(guò)程中出bug了 筷厘。driver.find_element_by_xpath這個(gè)句子我似乎見(jiàn)過(guò),翻入門(mén)書(shū)發(fā)現(xiàn)宏所,是selenium里的語(yǔ)句酥艳,意思是通過(guò)xpath這種方式來(lái)尋找元素。

后面的后綴很容易猜爬骤,clear()意思是清空內(nèi)容充石,sen_keys()意思是填入內(nèi)容,click()意思是點(diǎn)擊霞玄,time.sleep(1)意思是程序休息1秒鐘骤铃。

于是我猜想可能是程序里面定位的位置錯(cuò)了吧。于是百度搜索selenium的find_element_by語(yǔ)句的用法講解坷剧,并搜索xpath相關(guān)的內(nèi)容惰爬,xpath后面是什么意思。搜索關(guān)鍵詞“selenium find_element_by”

按F12打開(kāi)開(kāi)發(fā)者工具听隐,點(diǎn)擊左側(cè)的箭頭按鈕,然后光標(biāo)移到頁(yè)面中你要定位的的區(qū)域哄啄,在下方就可以看到當(dāng)前區(qū)域的代碼塊雅任。此時(shí)點(diǎn)擊右鍵风范,下方代碼就定位到這個(gè)代碼塊,在這個(gè)代碼塊再點(diǎn)擊右鍵沪么,copy-xpath硼婿,我粘貼到其他地方,發(fā)現(xiàn)復(fù)制的代碼和原代碼里xpath()的內(nèi)容很相似禽车。我猜想寇漫,只需要替換xpath()里的代碼就可以正確定位了。

image

替換了xpath里的內(nèi)容后殉摔,再運(yùn)行程序州胳,自動(dòng)填充賬號(hào)密碼的動(dòng)作果真完成了。

注意逸月,原代碼是進(jìn)入微信公眾平臺(tái)登陸頁(yè)面后就直接填寫(xiě)賬號(hào)密碼了栓撞,而我登陸微信公眾平臺(tái)時(shí)發(fā)現(xiàn)優(yōu)先項(xiàng)是先掃二維碼,于是模仿原代碼用driver.find_element_by_xpath語(yǔ)句加了個(gè)點(diǎn)擊輸入賬號(hào)密碼的動(dòng)作碗硬。

<pre>def login(username, password):
#打開(kāi)微信公眾號(hào)登錄頁(yè)面
driver.get('https://mp.weixin.qq.com/')
#driver.get('https://mp.weixin.qq.com/cgi-bin/loginpage?t=wxm2-login&lang=zh_CN')
driver.maximize_window()
time.sleep(3)
driver.find_element_by_xpath("http://[@id="header"]/div[2]/div/div/div[2]/a").click()
# 自動(dòng)填充帳號(hào)密碼
driver.find_element_by_xpath("http://
[@id="header"]/div[2]/div/div/div[1]/form/div[1]/div[1]/div/span/input").clear()
driver.find_element_by_xpath("http://[@id="header"]/div[2]/div/div/div[1]/form/div[1]/div[1]/div/span/input").send_keys(username)
driver.find_element_by_xpath("http://
[@id="header"]/div[2]/div/div/div[1]/form/div[1]/div[2]/div/span/input").clear()
driver.find_element_by_xpath("http://*[@id="header"]/div[2]/div/div/div[1]/form/div[1]/div[2]/div/span/input").send_keys(password)

time.sleep(1)
#自動(dòng)點(diǎn)擊登錄按鈕進(jìn)行登錄
driver.find_element_by_xpath("http://*[@id=\"header\"]/div[2]/div/div/div[1]/form/div[4]/a").click()
# 拿手機(jī)掃二維碼瓤湘!
time.sleep(15)</pre>

后來(lái)我想,既然之后還要掃二維碼恩尾,其實(shí)這段代碼可以簡(jiǎn)化弛说,不用輸入賬號(hào)密碼,直接最開(kāi)始就掃二維碼就行了吧翰意。

解決bug3

掃碼登陸后木人,要點(diǎn)擊新建圖文素材打開(kāi)一個(gè)新頁(yè)面,每次打開(kāi)新頁(yè)面后程序就停止了猎物,chrome瀏覽器地址欄提醒已攔截不被信任的flash虎囚,我猜想是瀏覽器的問(wèn)題,于是去瀏覽器里設(shè)置信任蔫磨,反復(fù)設(shè)置之后依然出現(xiàn)攔截淘讥,猜想這就是傳說(shuō)中的反爬蟲(chóng)機(jī)制生效了吧。

于是搜索selenium相關(guān)的反爬蟲(chóng)策略如何解決堤如。找了好久解決方案蒲列,都沒(méi)有合適的。后來(lái)頓悟搀罢,既然掃二維碼那一步可以手動(dòng)完成蝗岖,那點(diǎn)擊鏈接跳到新頁(yè)面的這一個(gè)動(dòng)作也手動(dòng)完成是不是就能跳過(guò)反爬蟲(chóng)機(jī)制呢。經(jīng)實(shí)驗(yàn)榔至,果然跳過(guò)了反爬蟲(chóng)機(jī)制抵赢。這是個(gè)本辦法,因?yàn)閲L試其他辦法可能會(huì)增加不少工作量,對(duì)于初學(xué)而言铅鲤,可以擱置在以后再嘗試划提。

解決bug4

在爬取url時(shí),本應(yīng)該不斷翻頁(yè)邢享,爬取所有url的鹏往,結(jié)果程序沒(méi)有實(shí)現(xiàn)翻頁(yè)。為了解決這個(gè)問(wèn)題骇塘,我加了個(gè)print數(shù)組的動(dòng)作伊履,以便發(fā)現(xiàn)爬取url的動(dòng)作是否實(shí)現(xiàn),爬取的數(shù)據(jù)是什么樣子款违。

以及分析翻頁(yè)這個(gè)動(dòng)作唐瀑,原代碼是怎么實(shí)現(xiàn)的。

<pre>page_num = int(driver.find_elements_by_class_name('weui-desktop-pagination__num__wrp')[-1].text.split('/')[-1])

點(diǎn)擊下一頁(yè)

url_title_lst = get_url_title(driver.page_source)

print(driver.page_source)

print(url_title_lst)

for _ in range(1, page_num):

for _ in range(1, page_num):

i =int(driver.find_elements_by_class_name('weui-desktop-pagination__num__wrp')[-1].text.split('/')[0])

    try:
        #pagination = driver.find_elements_by_class_name('pagination')[1]
        pagination = driver.find_elements_by_class_name('weui-desktop-pagination__nav')[-1]
        pagination.find_elements_by_tag_name('a')[-1].click()
        time.sleep(5)
        url_title_lst += get_url_title(driver.page_source)</pre>

于是去查找?guī)讉€(gè)代碼的含義奠货,來(lái)解讀整句代碼的意思介褥。了解了原理是提取頁(yè)碼的文本,當(dāng)當(dāng)前頁(yè)碼小于總頁(yè)碼數(shù)時(shí)递惋,就執(zhí)行翻頁(yè)動(dòng)作柔滔,當(dāng)當(dāng)前頁(yè)碼數(shù)等于總頁(yè)碼數(shù)時(shí),就停止執(zhí)行翻頁(yè)動(dòng)作萍虽。于是按照這個(gè)動(dòng)作邏輯睛廊,來(lái)查找現(xiàn)有代碼的錯(cuò)誤。嘗試了很多種語(yǔ)法可能杉编,最終找到了跑通這段程序的方式超全,獲得了完整的url。

解決bug5

已經(jīng)獲得了數(shù)組邓馒,然后要把數(shù)據(jù)保存到csv文件嘶朱,發(fā)現(xiàn)保存后的格式有問(wèn)題。由于是數(shù)組里包含大量字典數(shù)據(jù)光酣,保存到csv里的形式是每個(gè)單元格保存一個(gè)字典疏遏,橫排保存。

而我們希望呈現(xiàn)的數(shù)據(jù)是每條數(shù)據(jù)呈現(xiàn)在一行單元格救军,豎向排列财异。

于是百度搜索“python 字典保存到csv文件”

最終完美解決問(wèn)題。附解決問(wèn)題后的代碼:

下面的url_title_1st是上面生成的url數(shù)組里包含字典的數(shù)據(jù)唱遭。

<pre>url_list = url_title_lst
with open('outputurl.csv','w',encoding="utf-8",newline='') as f:
writer = csv.DictWriter(f, fieldnames=['date','url', 'title'])
writer.writeheader()
writer.writerows(url_list)</pre>

解決bug6

現(xiàn)在任務(wù)只剩下通過(guò)url地址生成pdf文檔了戳寸,看起來(lái)一步之遙。然而……

我看知乎上或者百度搜索的使用pdfkit生成pdf的代碼拷泽,要么是只將一個(gè)網(wǎng)頁(yè)轉(zhuǎn)換成pdf文件疫鹊,要么是在代碼中列舉多個(gè)url袖瞻。可是我有數(shù)百個(gè)url拆吆,寫(xiě)進(jìn)代碼多麻煩啊虏辫。能否直接用python傳入csv文件里的所有url,生成pdf呢锈拨。

我閱讀pdfkit包的說(shuō)明文檔,觀察pdfkit的傳入url的方法羹唠;猜想奕枢,只要我傳入的是url數(shù)組,那應(yīng)該就可以達(dá)到目的佩微。

<pre>pdfkit.from_url(['google.com', 'yandex.ru', 'engadget.com'], 'out.pdf')
pdfkit.from_file(['file1.html', 'file2.html'], 'out.pdf')</pre>

于是我的任務(wù)現(xiàn)在轉(zhuǎn)化為缝彬,將之前生成的數(shù)組包含字典的數(shù)據(jù)格式,變?yōu)橹话瑄rl的數(shù)組格式哺眯」惹常或者將本來(lái)包含多列數(shù)據(jù)的csv文件,提取其中url那一列生成只有url的數(shù)組奶卓。

于是百度搜索一疯,關(guān)鍵詞“python 數(shù)組含字典”,搜索了一陣子夺姑,終于看到我想要的解決方案了墩邀。

<pre>I have a list of dictionaries, and I need to get a list of the values from a given key from the dictionary (all the dictionaries have those same key).
For example, I have:
l = [ { "key": 1, "Val1": 'val1 from element 1', "Val2": 'val2 from element 1' },
{ "key": 2, "Val1": 'val1 from element 2', "Val2": 'val2 from element 2' },
{ "key": 3, "Val1": 'val1 from element 3', "Val2": 'val2 from element 3' } ]
I need to get 1, 2, 3.
Of course, I can get it with:
v=[]
for i in l:
v.append(i['key'])
But I would like to get a nicer way to do so.
解決方案
Using a simple list comprehension (if you're sure every dictionary has the key):
In [10]: [d['key'] for d in l]
Out[10]: [1, 2, 3]
Otherwise you'll need to check for existence first:
In [11]: [d['key'] for d in l if 'key' in d]
Out[11]: [1, 2, 3]</pre>

我于是模仿著寫(xiě)了以下代碼,果然打印出了url數(shù)組:

<pre>url_title=[]
for i in url_title_lst:
url_title.append(i['url'])
print(url_title)</pre>

如果是從csv文件中提取url數(shù)組盏浙,又該怎么做呢?

百度搜索“python csv文件中讀取數(shù)組”,試了網(wǎng)上的一些方式轻庆,都bug了般又,最后找到一種可行方式。

<pre>csvrows =[]
csvFileobj = open('out.csvpip','r',encoding='UTF-8')
readerobj = csv.reader(csvFileobj)
for row in readerobj:
if readerobj.line_num == 1:
continue
csvrows.append(row)
csvFileobj.close()
print(csvrows)</pre>

這個(gè)代碼的思路是丐黄,由于第一行是表頭斋配,跳過(guò)不讀。一行行的讀孵稽,每讀一行许起,就把讀的這一行加到之前的數(shù)組里,這樣整個(gè)文件讀完了菩鲜,數(shù)組也就產(chǎn)生了园细。

應(yīng)該還有其他可行方法,就留待以后開(kāi)展別的項(xiàng)目時(shí)再學(xué)接校。

解決bug7

現(xiàn)在有了一個(gè)包含多列數(shù)據(jù)的數(shù)組猛频。如何只提取url那一列生成新的數(shù)組呢狮崩。

再次百度搜索“python 讀取數(shù)組中某一列”,找到了方法:

<pre>>>> a=[[1,2,3],[4,5,6]]

a[0] #取一行
[1, 2, 3]
a[:,0] #嘗試用數(shù)組的方法讀取一列失敗
TypeError: list indices must be integers or slices, not tuple
? 我們需要用列表解析的方法讀取一列:
b=[x[0] for x in a]
print(b)
[1, 4]</pre>

所以我用以下代碼提取數(shù)組中的某一列:

<pre>url = [x[1] for x in csvrows]
print(url)</pre>

打印成功了鹿寻。

代步車造出來(lái)了睦柴!

經(jīng)過(guò)一系列的解決bug后,代碼終于成功生成了pdf文檔毡熏。雖然仍然存在一些待解決的問(wèn)題坦敌,但是我心中一種成就感油然而生,總算入門(mén)了痢法,總算邁過(guò)了容易放棄的痛苦期了狱窘。這就是自學(xué)python死磕一周的成果。

image

仍然有一些待解決的問(wèn)題财搁,比如:

1蘸炸、同一ip短時(shí)間頻繁訪問(wèn)一個(gè)公眾號(hào)的歷史文章,有時(shí)服務(wù)器會(huì)拒絕訪問(wèn)尖奔。

2搭儒、沒(méi)有生成目錄√嶙拢看了pdfkit淹禾,似乎需要先有個(gè)目錄文件才能生成,如何生成這個(gè)目錄文件呢茴扁。

3稀拐、沒(méi)有導(dǎo)出圖片。網(wǎng)上看到一些人提出了同樣的問(wèn)題丹弱。

4德撬、我導(dǎo)出不到200篇文章的pdf時(shí),可行躲胳,但是導(dǎo)出一個(gè)有600多篇文章的pdf時(shí)失敗了蜓洪,猜想可能是url數(shù)組太長(zhǎng)了,需要尋找解決方案坯苹。

學(xué)習(xí)一門(mén)技術(shù)的心得

學(xué)習(xí)一項(xiàng)技能隆檀,都有一條前期平緩后期陡峭的學(xué)習(xí)曲線,學(xué)習(xí)一項(xiàng)技能的初期粹湃,投入的精力成本雖然較高恐仑,但可見(jiàn)的進(jìn)步卻微小,讓人缺乏成就感为鳄,看不到希望裳仆,而一旦跨越了某個(gè)轉(zhuǎn)折點(diǎn),花費(fèi)同樣的精力孤钦,獲得的進(jìn)步卻變得非常明顯歧斟。只要能夠跨過(guò)這一拐點(diǎn)纯丸,學(xué)習(xí)這項(xiàng)技能的成功率就會(huì)大幅提升,并且很容易走向精通静袖。

image

推動(dòng)一個(gè)人行動(dòng)起來(lái)的策略觉鼻,大體有兩個(gè)方向:1、給他足夠強(qiáng)的驅(qū)動(dòng)力队橙,2坠陈、讓事情變得更容易辦到。

我吸取了前兩次學(xué)習(xí)失敗的教訓(xùn)捐康,做了一些改進(jìn)策略畅姊。

1、讓學(xué)習(xí)的啟動(dòng)更加簡(jiǎn)單吹由。

從安裝各種軟件,學(xué)習(xí)復(fù)雜的安裝步驟朱嘴。到選擇pycharm簡(jiǎn)化安裝步驟倾鲫。

2、細(xì)分目標(biāo)萍嬉,將整個(gè)項(xiàng)目分解成多個(gè)階段目標(biāo)乌昔,從而降低難度。

將一個(gè)項(xiàng)目任務(wù)壤追,分解為三個(gè)分階段目標(biāo)磕道,其中兩個(gè)階段我有信心完成,又將剩下的目標(biāo)分解為需要不斷克服的各種bug行冰,每克服一個(gè)bug我都能感受到項(xiàng)目離成功更近了一步溺蕉。

3、簡(jiǎn)化一些暫時(shí)不大需要的學(xué)習(xí)任務(wù)悼做,緊抓核心任務(wù)疯特。

我在這個(gè)項(xiàng)目中放棄了補(bǔ)習(xí)數(shù)據(jù)庫(kù)的知識(shí),放棄了補(bǔ)習(xí)fidler抓包肛走,以及如何提取json文件中信息的知識(shí)漓雅,放棄了代理ip反爬蟲(chóng)的知識(shí),放棄了尋找全自動(dòng)爬蟲(chóng)的解決方法而選擇暫時(shí)用半自動(dòng)爬蟲(chóng)朽色。

4邻吞、尋找讓python學(xué)習(xí)變得更有價(jià)值得學(xué)習(xí)目標(biāo)。

我最開(kāi)始從數(shù)據(jù)分析的角度學(xué)習(xí)python葫男,然而少量數(shù)據(jù)分析可以用excel等工具迅速完成抱冷,大數(shù)據(jù)的分析暫時(shí)沒(méi)有施展機(jī)會(huì)。后來(lái)從爬蟲(chóng)的角度入手python梢褐,爬蟲(chóng)是每一個(gè)個(gè)體都可以學(xué)習(xí)并應(yīng)用的領(lǐng)域徘层,起碼可以幫助自己備份一些信息資料峻呕,進(jìn)一步地可以通過(guò)網(wǎng)上爬到的數(shù)據(jù)進(jìn)行數(shù)據(jù)分析,做一些數(shù)據(jù)分析作品出來(lái)趣效,再進(jìn)一步地瘦癌,可以用來(lái)運(yùn)作商業(yè)項(xiàng)目。

只要方法對(duì)了跷敬,你也可以一周入門(mén)python讯私,或短時(shí)間學(xué)會(huì)某種技術(shù)。

分享轉(zhuǎn)發(fā)這篇文章西傀,為你的學(xué)習(xí)立下一個(gè)Flag吧斤寇!

在公眾號(hào)【江流】后臺(tái)回復(fù)關(guān)鍵詞“python”可以獲得文中提到的自學(xué)python用到的資源鏈接,如何找到可用的pycharm激活碼拥褂,并限量幫50個(gè)讀者導(dǎo)出pdf版公眾號(hào)歷史文集娘锁。

之后,我可能還會(huì)繼續(xù)在公眾號(hào)【江流】更新我學(xué)習(xí)python的進(jìn)展報(bào)告饺鹃。也希望與更多學(xué)習(xí)者交流莫秆。歡迎后臺(tái)留言。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悔详,一起剝皮案震驚了整個(gè)濱河市镊屎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茄螃,老刑警劉巖缝驳,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異归苍,居然都是意外死亡用狱,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)拼弃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)齿拂,“玉大人,你說(shuō)我怎么就攤上這事肴敛∈鸷#” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵医男,是天一觀的道長(zhǎng)砸狞。 經(jīng)常有香客問(wèn)我,道長(zhǎng)镀梭,這世上最難降的妖魔是什么刀森? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮报账,結(jié)果婚禮上研底,老公的妹妹穿的比我還像新娘埠偿。我一直安慰自己,他們只是感情好榜晦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布冠蒋。 她就那樣靜靜地躺著,像睡著了一般乾胶。 火紅的嫁衣襯著肌膚如雪抖剿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天识窿,我揣著相機(jī)與錄音斩郎,去河邊找鬼。 笑死喻频,一個(gè)胖子當(dāng)著我的面吹牛缩宜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播甥温,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锻煌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了窿侈?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤秋茫,失蹤者是張志新(化名)和其女友劉穎史简,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體肛著,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡圆兵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了枢贿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殉农。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖局荚,靈堂內(nèi)的尸體忽然破棺而出超凳,到底是詐尸還是另有隱情,我是刑警寧澤耀态,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布轮傍,位于F島的核電站,受9級(jí)特大地震影響首装,放射性物質(zhì)發(fā)生泄漏创夜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一仙逻、第九天 我趴在偏房一處隱蔽的房頂上張望驰吓。 院中可真熱鬧涧尿,春花似錦、人聲如沸檬贰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)偎蘸。三九已至庄蹋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迷雪,已是汗流浹背限书。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留章咧,地道東北人倦西。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像赁严,于是被迫代替她去往敵國(guó)和親扰柠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355