日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

使用 Python 抓取知乎美圖(文末含福利)知乎釣魚貼匯總

系統(tǒng) 2024 0

福利

當(dāng)我們爬蟲寫好,入庫,并成功展示出來,不知不覺就實(shí)現(xiàn)了一個(gè)小程序項(xiàng)目: 宅宅生活收藏夾

微信搜索小程序:宅宅生活收藏夾。歡迎大家使用。
使用 Python 抓取知乎美圖(文末含福利)知乎釣魚貼匯總_第1張圖片
使用 Python 抓取知乎美圖(文末含福利)知乎釣魚貼匯總_第2張圖片

之前寫到 宅宅生活收藏夾 的部署方法,見 使用Flask,Nginx,
Gunicorn,Supervisor完成網(wǎng)站部署。這次介紹一下如何抓取知乎答案,獲取知乎美圖。

本文除 Python 相關(guān)庫的使用外,還會(huì)涉及到 mongo 數(shù)據(jù)庫的使用。

因?yàn)? 宅宅生活收藏夾 只是為了收集知乎釣魚貼的圖片,有針對性,所以不能通過獲取知乎首頁列表全面抓取。當(dāng)然抓取方式大同小異,把抓取列表改為知乎首頁也是可以的。

整體思路

首先我們需要收集知乎各類釣魚貼,這一步可以使用爬蟲(通過爬取別人已經(jīng)收集的釣魚貼,或者各種社區(qū)可能已有釣魚貼專欄等)獲取,也可以在瀏覽知乎時(shí),發(fā)現(xiàn)合適的貼子手動(dòng)添加。

我們需要將釣魚貼的 ID 存入數(shù)據(jù)庫中,爬蟲運(yùn)行時(shí)讀庫獲取需要爬取的目標(biāo)貼。

通過寫一個(gè)爬蟲,生成任務(wù)池多線程調(diào)用。將獲取到的答案數(shù)據(jù)清洗,只收集答案中的圖片。

存入庫中的結(jié)構(gòu)和知乎的類似:答案集合保存所有答案,每一個(gè)答案是一條獨(dú)立的文檔。可能寫的有點(diǎn)繞。

具體結(jié)構(gòu)類似這種結(jié)構(gòu):

            
              
                {
              
              
                "Answer"
              
              
                :
              
              
                [
              
              
                {
              
              
                "id"
              
              
                :
              
              
                1
              
              
                ,
              
              
                "question_id"
              
              
                :
              
              
                "xxx"
              
              
                ,
              
              
                "title"
              
              
                :
              
              
                "xxx"
              
              
                ,
              
              
                "author"
              
              
                :
              
              
                "xxx"
              
              
                ,
              
              
            "content
              
                :
              
              
                [
              
              
                "imgUrl"
              
              
                ,
              
              
                "..."
              
              
                ]
              
              
                }
              
              
                ,
              
              
                {
              
              
                "id"
              
              
                :
              
              
                2
              
              
                ,
              
              
                "question_id"
              
              
                :
              
              
                "xxx"
              
              
                ,
              
              
                "title"
              
              
                :
              
              
                "xxx"
              
              
                ,
              
              
                "author"
              
              
                :
              
              
                "xxx"
              
              
                ,
              
              
            "content
              
                :
              
              
                [
              
              
                "imgUrl"
              
              
                ,
              
              
                "..."
              
              
                ]
              
              
                }
              
              
                ,
              
              
                ...
              
              
                ]
              
              
                }
              
            
          

其中 Answer 為數(shù)據(jù)庫的集合,集合中的每一項(xiàng)是一條回答。

用這種格式保存的好處是我們只需通過貼子的 ID 查詢答案即可,保存起來也非常方便。

知乎爬蟲

開始之前

在開始之前需要安裝項(xiàng)目依賴,只用到兩個(gè)常用庫:

python3 -m pip install requests pymongo

分別用來爬蟲和操作數(shù)據(jù)庫。

安裝完成后記得啟動(dòng) mongo 服務(wù)。

Spider

爬蟲代碼比較簡單,代碼不過百行,關(guān)鍵找到知乎答案的接口,解析即可。而且這個(gè)接口也是非常好找的。

用 Chrome 的開發(fā)者工具一下就找到了…

[外鏈圖片轉(zhuǎn)存失敗(img-waDRfOCu-1562419272787)(https://user-images.githubusercontent.com/25655581/60421921-64c30d80-9c1d-11e9-9c45-7e4cdbe1b38a.png)]

而且接口也沒有任何加密或權(quán)限限制,在請求頭中加入 Cookies 就可以了。是不是突然覺得很簡單?

只要我們控制好頻率,不要影響到知乎服務(wù)就行了。畢竟我們只是想獲取答案而已,不想做其他的。

通過 Chrome 開發(fā)者工具分析,請求攜帶了如下參數(shù),我們只用到 limit offset ,用來控制接口返回的數(shù)量和返回的位置。

            
              include: data[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,is_labeled,is_recognized,paid_info;data[*].mark_infos[*].url;data[*].author.follower_count,badge[*].topics
offset:
limit: 3
sort_by: default
platform: desktop

            
          

完整的請求 URL 是:

https://www.zhihu.com/api/v4/questions/21115811/answers?include=data%5B*%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%2Cis_recognized%2Cpaid_info%3Bdata%5B*%5D.mark_infos%5B*%5D.url%3Bdata%5B*%5D.author.follower_count%2Cbadge%5B*%5D.topics&offset=&limit=3&sort_by=default&platform=desktop

我們只要?jiǎng)討B(tài)更改其中的 question limit offset 就可以了。

我們通過接口返回的答案總數(shù),判斷需要翻多少頁,當(dāng)然也可以通過接口返回的 next previous 來獲取下一頁或前一頁答案鏈接。知乎的接口設(shè)計(jì)的非常方便啊。

當(dāng)然在翻頁抓取的時(shí)候切記設(shè)置睡眠時(shí)間,放在服務(wù)器上爬的慢一點(diǎn)也沒關(guān)系。 不要影響到知乎的正常服務(wù)

請求成功后我們就可以根據(jù)自己的需求,存儲(chǔ)數(shù)據(jù)了,至于如何判斷答案中是否有圖片,可以參考以下代碼。

使用到了 lxml ,也可以使用 re 庫代替。

            
              @
              
                staticmethod
              
              
                def
              
              
                parse_content
              
              
                (
              
              self
              
                ,
              
               content
              
                )
              
              
                :
              
              
                """解析答案中的 content,直接獲取圖片"""
              
              
                if
              
              
                "
                
                
                  in
                
                 content
                
                  :
                
                
        img_list 
                
                  =
                
                
                  set
                
                
                  (
                
                etree
                
                  .
                
                HTML
                
                  (
                
                content
                
                  )
                
                
                  .
                
                xpath
                
                  (
                
                
                  "http://img/@data-original"
                
                
                  )
                
                
                  )
                
                
                  return
                
                
                  list
                
                
                  (
                
                img_list
                
                  )
                
                
                  else
                
                
                  :
                
                
                  return
                
                
                  [
                
                
                  ]
                
              
            
          

先判斷回答中是否有 img 標(biāo)簽,如果沒有直接返回空列表,如果有的話,通過 data-original 屬性獲取原始大小的圖片鏈接。也是返回列表類型。

在入庫的時(shí)候,我們通過 parse_content 的返回判斷是否需要入庫,如果是 [] 就跳過,如果列表不為空就入庫。這樣在之后展示的時(shí)候不會(huì)只展示作者信息,卻沒有回答的情況了(其實(shí)是該作者回答中沒有圖片)。

調(diào)用爬蟲

當(dāng)我們完成上述操作,就可以單獨(dú)寫一個(gè)文件使用多線程調(diào)用爬蟲了。

            
              
                from
              
               concurrent
              
                .
              
              futures 
              
                import
              
               ThreadPoolExecutor

qid_list 
              
                =
              
               db
              
                .
              
              get_all_question
              
                (
              
              
                )
              
              
crawler_list 
              
                =
              
              
                [
              
              ZhihuSpider
              
                (
              
              qid
              
                )
              
              
                .
              
              run 
              
                for
              
               qid 
              
                in
              
               qid_list
              
                ]
              
              
                with
              
               ThreadPoolExecutor
              
                (
              
              max_workers
              
                =
              
              
                4
              
              
                )
              
              
                as
              
               executor
              
                :
              
              
    future 
              
                =
              
              
                [
              
              executor
              
                .
              
              submit
              
                (
              
              task
              
                )
              
              
                for
              
               task 
              
                in
              
               crawler_list
              
                ]
              
              
                for
              
               f 
              
                in
              
               future
              
                :
              
              
        f
              
                .
              
              result
              
                (
              
              
                )
              
            
          

qid_list 來自查庫獲取所有的知乎貼子 ID。

使用 concurrent.futures 庫并行執(zhí)行任務(wù),在我們的代碼里使用 ThreadPoolExecutor ,它使用線程池來異步執(zhí)行調(diào)用。

max_workers 控制最多線程的使用,本例中使用最多4個(gè)線程執(zhí)行任務(wù)。

具體文檔見 ThreadPoolExecutor,是對 thread 庫的封裝,讓我們使用線程時(shí)更加簡單。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 恭城| 裕民县| 西吉县| 昌吉市| 沛县| 乐亭县| 大洼县| 富锦市| 克什克腾旗| 六安市| 涟水县| 武定县| 梓潼县| 天镇县| 黔西| 平南县| 无为县| 鹤庆县| 甘肃省| 苍南县| 怀集县| 墨玉县| 仙游县| 宾阳县| 共和县| 凉山| 沙雅县| 北川| 泽普县| 綦江县| 康马县| 会东县| 茂名市| 大足县| 五常市| 伊宁市| 天门市| 湖口县| 堆龙德庆县| 闽侯县| 德保县|