python3爬蟲(chóng)學(xué)習(xí)之?dāng)?shù)據(jù)存儲(chǔ)txt的案例詳解
上一篇實(shí)戰(zhàn)爬取知乎熱門話題的實(shí)戰(zhàn),并且保存為本地的txt文本
先上代碼,有很多細(xì)節(jié)和坑需要規(guī)避,弄了兩個(gè)半小時(shí)
import requests import re headers = { "user-agent" : "Mozilla/5.0 (Windows NT 6.1; Win64; x64)" " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari" "/537.36M", "cookie" : '_xsrf=H6hRg3qQ9I1O8jRZOmf4ytecfaKdf2es; _zap=296584df-ce11-4059-bc93-be10eda0fdc1; d_c0="AKBmB5e-PA-PTkZTAD1nQun0qMf_hmcEH14=|1554554531"; ' 'capsion_ticket="2|1:0|10:1554554531|14:capsion_ticket|44:Yjc0NjAzNDViMTIzNDcyZDg2YTZjYTk0YWM3OGUzZDg=|2d7f136328b50cdeaa85e2605e0be2bb931d406babd396373d15d5f8a6c' '92a61"; l_n_c=1; q_c1=ad0738b5ee294fc3bd35e1ccb9e62a11|1554554551000|1554554551000; n_c=1; __gads=ID=9a31896e052116c4:T=1554555023:S=ALNI_Mb-I0et9W' 'vgfQcvMUyll7Byc0XpWA; tgw_l7_route=116a747939468d99065d12a386ab1c5f; l_cap_id="OGEyOTkzMzE2YmU3NDVmYThlMmQ4OTBkMzNjODE4N2Y=|1554558219|a351d6740bd01ba8ee34' '94da0bd8b697b20aa5f0"; r_cap_id="MDIzNThmZjRhNjNlNGQ1OWFjM2NmODIxNzNjZWY2ZjY=|1554558219|ff86cb2f7d3c6e4a4e2b1286bbe0c093695bfa1d"; cap_id="MGNkY2RiZTg5N2MzNDUyNTk0NmEzMTYyYzgwY' 'zdhYTE=|1554558219|18ed852d4506efb2345b1dbe14c749b2f9104d54"; __utma=51854390.789428312.1554558223.1554558223.1554558223.1; __utmb=51854390.0.10.1554558223; __utmc=51854390; ' '__utmz=51854390.1554558223.1.1.utmcsr=(direct' ')|utmccn=(direct)|utmcmd=(none); __utmv=51854390.000--|3=entry_date=20190406=1', "authority" : "www.zhihu.com", } url = "https://www.zhihu.com/explore" response = requests.get(url=url , headers=headers) text = response.text # print(text) titles = [] f_titles = re.findall(r'<div class="explore-feed feed-item".*?>.*?<a class="question_link".*?>(.*?)</a>.*?</h2>',text,re.S) for title in f_titles: titles.append(title.strip()) # print("*"*30) authors = [] f_authors = re.findall(r'<div class="zm-item-answer-author-info".*?>(.*?)</span>',text,re.S)[1:] for f_author in f_authors: # print(f_author) author = re.sub(r'<.*?>|<a ([^>]*?)>' , "" , f_author,re.S).strip() authors.append(author) # print("*"*30) content_urls = re.findall(r'<div class="zh-summary summary clearfix">.*?<a href="(.*?)" rel="external nofollow" rel="external nofollow" .*?>.*?</a>',text,re.S)[1:] contents = [] for content_url in content_urls: content_full_url = "https://www.zhihu.com" + content_url # print(content_full_url) resp = requests.get(url=content_full_url , headers=headers) c_text = resp.text content = re.findall(r'<div class="RichContent-inner">*?<span .*?>(.*?)</span>',c_text,re.S) content = str(content) # print(type(content)) cont = re.sub(r'\\n|<.*?>',"",content).strip() # print(cont) contents.append(cont) zhihu_questions = [] for value in zip(titles,authors,contents): title,author,content = value zhihu_question = { "標(biāo)題" : title, "作者" : author, "內(nèi)容" : content } zhihu_questions.append(zhihu_question) # for zhihu_question in zhihu_questions: # for value in zhihu_question.values(): # print(value) # print("=" * 50) with open("知乎.txt" , "a" , encoding="utf-8") as fp: for zhihu_question in zhihu_questions: for value in zhihu_question.values(): fp.write(value) fp.write('\n' + "="*10 + '\n') fp.write('\n' + "*"*50 + '\n')
我們用requests庫(kù)和正則來(lái)爬取
因?yàn)橐恢睖y(cè)試爬取內(nèi)容是否正確,可能運(yùn)行太頻繁,博主中間被封了一次號(hào),然后修改了cookie等信息,勉強(qiáng)獲取到了內(nèi)容。
正則表達(dá)式在之前講的很多了,也有過(guò)實(shí)戰(zhàn),不多贅述,我們主要來(lái)講爬取時(shí)遇到的問(wèn)題。
爬取標(biāo)題時(shí)很順利,我們只需要去除空白就行了
當(dāng)爬取作者時(shí)就有了問(wèn)題,我們注意到,熱門話題共有10篇,也就是10個(gè)作者,但在用正則獲取時(shí),要么第一個(gè)作者不對(duì),要么就只有9個(gè)作者,我把所有熱門話題url,標(biāo)題,作者和內(nèi)容打印出來(lái),打開(kāi)瀏覽器一個(gè)一個(gè)對(duì)應(yīng)標(biāo)題作者和內(nèi)容是否正確,發(fā)現(xiàn)了一個(gè)神奇的現(xiàn)象。
一:作者數(shù)量不對(duì)
在知乎有匿名作者,這種作者和不匿名的作者都放在同一種div下,但匿名作者在span標(biāo)簽內(nèi),而不匿名作者在a標(biāo)簽下,所以當(dāng)我用正則匹配a標(biāo)簽的內(nèi)容,無(wú)法獲取匿名用戶,就導(dǎo)致作者數(shù)量不對(duì)。于是直接獲取div下的所有內(nèi)容,在用sub去掉不要的內(nèi)容
二:作者與標(biāo)題或內(nèi)容不符
1是第一個(gè)作者,他不是我們需要的,但我們爬取的第一個(gè)就是他,2才是熱門的第一個(gè)作者
未獲取匿名用戶
這兩個(gè)是我們無(wú)法正常獲取的原因
上面兩個(gè)問(wèn)題這樣解決:
f_authors = re.findall(r'<div class="zm-item-answer-author-info".*?>(.*?)</span>',text,re.S)[1:] for f_author in f_authors: # print(f_author) author = re.sub(r'<.*?>|<a ([^>]*?)>' , "" , f_author,re.S).strip() authors.append(author)
獲取所有未經(jīng)處理的作者,我們不要第一個(gè)因?yàn)樗皇菬衢T話題的回答者,f_authors是含有大量標(biāo)簽的列表,大家可以打印看看
我們遍歷這個(gè)未經(jīng)處理的列表,打印未經(jīng)處理的作者名,看看需要處理什么。
我們發(fā)現(xiàn)含有大量span標(biāo)簽和a標(biāo)簽,我們用sub函數(shù)處理
三:我們可以發(fā)現(xiàn),這些內(nèi)容是很長(zhǎng)的:
這樣,我們獲取的內(nèi)容是不正常的,我們分析可以找到該話題對(duì)應(yīng)的鏈接,我們加上域名就可以到這個(gè)話題的詳情頁(yè)
我們獲取url,處理頁(yè)面,獲取內(nèi)容,將獲取的內(nèi)容去掉標(biāo)簽等無(wú)關(guān)內(nèi)容即可。
content_urls = re.findall(r'<div class="zh-summary summary clearfix">.*?<a href="(.*?)" rel="external nofollow" rel="external nofollow" .*?>.*?</a>',text,re.S)[1:] contents = [] for content_url in content_urls: content_full_url = "https://www.zhihu.com" + content_url # print(content_full_url) resp = requests.get(url=content_full_url , headers=headers) c_text = resp.text content = re.findall(r'<div class="RichContent-inner">*?<span .*?>(.*?)</span>',c_text,re.S) content = str(content) # print(type(content)) cont = re.sub(r'\\n|<.*?>',"",content).strip() # print(cont) contents.append(cont)
關(guān)于zip函數(shù),我在上一篇爬取古詩(shī)文也用到了,很重要的函數(shù):
zhihu_questions = [] for value in zip(titles,authors,contents): title,author,content = value zhihu_question = { "標(biāo)題" : title, "作者" : author, "內(nèi)容" : content } zhihu_questions.append(zhihu_question)
最后就是把獲取的內(nèi)容保存為本地txt文檔
with open("知乎.txt" , "a" , encoding="utf-8") as fp: for zhihu_question in zhihu_questions: for value in zhihu_question.values(): fp.write(value) fp.write('\n' + "="*10 + '\n') fp.write('\n' + "*"*50 + '\n')
這是最基本的保存爬取內(nèi)容的方法。后續(xù)會(huì)有json,csv,數(shù)據(jù)庫(kù)的相關(guān)博客續(xù)上。
運(yùn)行結(jié)果:
另,注釋代碼都是測(cè)試代碼,可以參考。
補(bǔ)充:可能看得時(shí)候cookie信息會(huì)過(guò)期。
補(bǔ)充:文件打開(kāi)的幾種方式
1:r:只讀模式,也是默認(rèn)模式
2:rb:二進(jìn)制只讀
3:r+:讀寫(xiě)方式
4:rb+:二進(jìn)制讀寫(xiě)方式
5:w:寫(xiě)方式
6:wb:二進(jìn)制寫(xiě)方式
7:w+:讀寫(xiě)方式
8:wb+:二進(jìn)制讀寫(xiě)方式
9:a:以追加方式,這個(gè)方式不會(huì)把原來(lái)的內(nèi)容覆蓋,本篇代碼以此方式打開(kāi)文件
10:ab:二進(jìn)制追加方式
11:a+:讀寫(xiě)方式
12:ab+:二進(jìn)制讀寫(xiě)方式
以上所述是小編給大家介紹的python3爬蟲(chóng)學(xué)習(xí)之?dāng)?shù)據(jù)存儲(chǔ)txt的案詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Python unittest生成測(cè)試報(bào)告過(guò)程解析
這篇文章主要介紹了Python unittest生成測(cè)試報(bào)告過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09Python使用Tkinter實(shí)現(xiàn)滾動(dòng)抽獎(jiǎng)器效果
Tkinter 是 Python 的標(biāo)準(zhǔn) GUI(Graphical User Interface,圖形用戶接口)庫(kù),Python 使用 Tkinter 可以快速地創(chuàng)建 GUI 應(yīng)用程序。這篇文章主要介紹了Python使用Tkinter實(shí)現(xiàn)滾動(dòng)抽獎(jiǎng)器,需要的朋友可以參考下2020-01-01Python word實(shí)現(xiàn)讀取及導(dǎo)出代碼解析
這篇文章主要介紹了Python word實(shí)現(xiàn)讀取及導(dǎo)出代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07python3?chromedrivers簽到的簡(jiǎn)單實(shí)現(xiàn)
本文主要介紹了python3?chromedrivers簽到的簡(jiǎn)單實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03python實(shí)現(xiàn)rsa加密實(shí)例詳解
這篇文章主要介紹了python實(shí)現(xiàn)rsa加密實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-07-07keras.layers.Conv2D()函數(shù)參數(shù)用法及說(shuō)明
這篇文章主要介紹了keras.layers.Conv2D()函數(shù)參數(shù)用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02Tensorflow:轉(zhuǎn)置函數(shù) transpose的使用詳解
今天小編就為大家分享一篇Tensorflow:轉(zhuǎn)置函數(shù) transpose的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02