<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python爬蟲:頭條小姐姐們都來給你拜年啦!

          共 7850字,需瀏覽 16分鐘

           ·

          2021-02-19 12:43


          覺得上面的小姐姐漂亮的,可以舉個爪子。

          今天就來教大家來爬取頭條上的美女。

          但是,不要著急,在學(xué)爬蟲之前,大家需要先學(xué)會分析Ajax請求。

          前言

          有時候我們會用requests抓取頁面的時候,得到的結(jié)果可能和瀏覽器中看到的不一樣:在瀏覽器中可以看到正常顯示的頁面數(shù)據(jù),但是使用requests得到的結(jié)果并沒有。這是因為requests獲取的是原始的HTML文檔,而瀏覽器中的頁面則是經(jīng)過javascript處理數(shù)據(jù)后生成的結(jié)果,這些數(shù)據(jù)的來源有多種,可能通過Ajax加載的,可能是包含在HTML文檔當(dāng)中,也有可能是經(jīng)過javascript特定算法計算后生成的。

          對于第一種情況:Ajax加載數(shù)據(jù)是一種異步加載方式,原始的農(nóng)業(yè)面最初是不會包含這些數(shù)據(jù)的,原始頁面加載完成之后,會再向服務(wù)器請求某個接口的數(shù)據(jù),然后數(shù)據(jù)就會被處理從而呈現(xiàn)到網(wǎng)頁上,這就是一個Ajax請求。

          按照目前web的發(fā)展形式,這種頁面會越來越多。網(wǎng)頁的原始HTML中不會包含任何的數(shù)據(jù),數(shù)據(jù)是通過Ajax統(tǒng)一加載后呈現(xiàn)出來的,這樣在web開發(fā)上可以做到前后分離,而且降低了服務(wù)器直接渲染頁面帶來的壓力。

          因此,直接利用requests來獲取原始HTML,是無法獲取到有效的數(shù)據(jù)的,這時需要分析網(wǎng)頁后臺向接口發(fā)送的Ajax請求,如果可以用requests來模擬Ajax請求,那么就可以正常抓取數(shù)據(jù)了。

          什么是Ajax

          Ajax是異步的javascript和xml。它不是一門編程語言,而是利用javascript保證頁面不被刷新,URL不變的情況下與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁的技術(shù)。

          對于傳統(tǒng)的網(wǎng)頁來說,要想更新數(shù)據(jù)就必須刷新整個頁面,但是有了Ajax之后,便可以在頁面不全部刷新的情況下更新內(nèi)容。在這個過程中實際上是在后臺與服務(wù)器進行了數(shù)據(jù)的交換,獲取到數(shù)據(jù)之后,再利用javascript改變網(wǎng)頁,這樣頁面就會刷新了。

          Ajax分析方法

          這里以微博為例,我們知道拖動刷新的內(nèi)容由Ajax加載,而且頁面的URL沒有任何變化,那么應(yīng)該去哪里查看這些Ajax請求呢?

          查看請求

          這里還需要借助瀏覽器的開發(fā)者工具,下面以Chrome瀏覽器為例子進行簡單的介紹。

          首先,打開微博的首頁隨便點擊任意一條微博,隨后在頁面中點擊鼠標(biāo)右鍵,從彈出的快捷鍵菜單中選擇“檢查”選項,此時就會彈出開發(fā)者工具,如下圖所示:

          此時在element選項卡中便會觀察到網(wǎng)頁的源代碼。不過這個不是我們需要尋找的內(nèi)容,切換到network選項卡,隨后重新刷新頁面,可以發(fā)現(xiàn)這里多出了不少的條目,如下圖所示:

          這里是頁面加載過程中瀏覽器與服務(wù)器之間發(fā)送請求和接收響應(yīng)的所有內(nèi)容。

          Ajax其實是特殊的請求類型,它叫做xhr。在下面的圖片中,我們可以看到以big為開頭的請求,其類型type為xhr,其實這個就是Ajax請求。

          鼠標(biāo)點擊該請求的時候,右側(cè)可以看到該請求的Request Headers、URL和Response Headers等信息。其中Request Headers中有個信息為x-requested-with: XMLHttpRequest,這個就是標(biāo)記此請求就是Ajax請求。如下圖所示:

          隨后點擊一下preview,即可看到響應(yīng)內(nèi)容,它是json格式的數(shù)據(jù),這里的Chrome為我們自動做了解析,點擊內(nèi)容即可展開和收起相應(yīng)的內(nèi)容。如下圖所示:

          由于里面的內(nèi)容較多,我將它復(fù)制下來,比較容易觀察。

          從上面的圖片可以觀察到,返回的內(nèi)容其實是評論者的昵稱、評論內(nèi)容、評論時間以及點贊數(shù)。

          另外,我們也可以切換到該頁面URL的請求,查看它的Response是什么,如下圖所示:

          經(jīng)過觀察,其實很容易發(fā)現(xiàn),這里的代碼非常簡單,除了簡單的HTML代碼之外,其他的都是javascript。所以說,我們看到的微博頁面的數(shù)據(jù)并不是原始的頁面返回的,而是后來執(zhí)行javascript后,再次向后臺發(fā)送的Ajax請求,瀏覽器拿到數(shù)據(jù)之后做進一步的渲染。

          過濾請求

          接下來利用瀏覽器中的開發(fā)者工具進行篩選,可以將Ajax請求全部篩選出來。在請求的上方有一層篩選欄,直接點擊XHR,此時在下方顯示的所有請求便都是Ajax請求了,如下圖所示:

          接下來,不斷的滑動頁面,可以看到頁面底部有一條條新的微博評論被刷出,而開發(fā)者工具下方也會有一個個Ajax請求出現(xiàn),這樣我們就可以捕捉到所有的Ajax請求了。如下圖所示:

          至此,我們基本上可以分析出Ajax請求的一些詳細信息了,接下來只需要用程序模擬這些Ajax請求,就可以輕松的獲取到我們需要的信息了。

          實戰(zhàn)

          分析Ajax爬取今日頭條小姐姐

          準(zhǔn)備工作

          在項目開始之前,請確保已經(jīng)安裝好requests庫,如果沒有安裝,請參考下面的安裝方法:

          pip?install?requests

          抓取分析

          在抓取之前,首先要分析抓取的邏輯。打開今日頭條的首頁:https://www.toutiao.com/

          在左上角有一個搜索接口,這里嘗試抓取美女圖片,所以輸入“美女”二字搜索一下,如下圖所示:

          這時打開開發(fā)者工具并刷新整個頁面,你會發(fā)現(xiàn)在network選項卡中會出現(xiàn)大量的數(shù)據(jù)請求信息。點擊第一個請求,并點擊response選項,搜索“寫真”,遺憾的事情發(fā)生了,里面沒有出現(xiàn)任何的關(guān)于寫真的字眼。

          因此,可以初步判斷這些內(nèi)容是由Ajax加載的,然后利用javascript渲染出來,接下來切換到XHR選項卡,查看有沒有Ajax請求,如下圖所示:

          不出所料,這里果然出現(xiàn)了一些比較常規(guī)的Ajax請求,看看它的結(jié)果是否包含了頁面中的相關(guān)數(shù)據(jù)。

          點擊data字段展開,發(fā)現(xiàn)這里許多條數(shù)據(jù)。點擊第一條展開,發(fā)現(xiàn)有article_url字段和title字段與網(wǎng)頁內(nèi)容基本符合。

          切換回headers選項卡,觀察URL和headers信息,如下圖所示:

          可以看到這是一個get請求,請求的URL參數(shù)有:aidapp_name、offsetformat、keywordautoloadcount、en_qc、cur_tab、from、pd、timestamp、_signature

          繼續(xù)下滑網(wǎng)頁,你會發(fā)現(xiàn)在XHR選項卡中會出現(xiàn)越來越多的符合條件的Ajax請求。

          如下所示:

          https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis×tamp=1612428382721&_signature=_02B4Z6wo00f015gKQTwAAIDAKPut9b7JdoeYL0WAAIYhGfqDyZWOUeA.JwSONVd37BCTuUrJwE1gIOy3vdsi5j5EDUTmLQeASGQij2uMyxRGe3E8Peoo2hzHzz5RwATyAVC1zu18zMfLZ5S3a

          https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=20&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis×tamp=1612429526639&_signature=_02B4Z6wo00d01lR4bAgAAIDB5ImAw3OJbZpUXWiAAPUUQO2SS7CFcMRjXUZZEIHjqP2egcZBSpXYmI6hWj.iKGkzEg0JBWChgQPoggOPf63cZGszmYGGuZdc1vbIO9gVPQmgwTOGo6qCxbjK94


          https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=40&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis×tamp=1612429531243&_signature=_02B4Z6wo00d01GfNiKwAAIDD1zxkZOf0K2hn6IwAAHnwQO2SS7CFcMRjXUZZEIHjqP2egcZBSpXYmI6hWj.iKGkzEg0JBWChgQPoggOPf63cZGszmYGGuZdc1vbIO9gVPQmgwTOGo6qCxbjKdd


          https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=60&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis×tamp=1612429538566&_signature=_02B4Z6wo00d01tH81gwAAIDBYQ06xI8rJLrR2dKAANRxQO2SS7CFcMRjXUZZEIHjqP2egcZBSpXYmI6hWj.iKGkzEg0JBWChgQPoggOPf63cZGszmYGGuZdc1vbIO9gVPQmgwTOGo6qCxbjK95

          通過觀察,可以發(fā)現(xiàn)變化的內(nèi)容有offset,timestamp_signature ? ?。

          timestamp指的是時間戳,而_signature指的是簽名認(rèn)證。我自己也看了很多的教程,大多數(shù)關(guān)于這個 _signature的破解其實是js的逆向。本來我也想要寫用js逆向來破解這個 _signature,但是想到大家對于js逆向的方法可能不熟悉,畢竟我還沒有寫過該類文章,因此就不用這個方法了。經(jīng)過測試發(fā)現(xiàn)不添加 _signature這個參數(shù),對于獲取json響應(yīng)并無影響。

          并且通過分析該Ajax請求可以發(fā)現(xiàn),里面有image_list字段,如下圖所示:

          將這三個URL地址依次復(fù)制到瀏覽器之后可以發(fā)現(xiàn),正是圖片的URL地址,但是需要注意的是這個并不是高清大圖的URL地址。

          那問題就出現(xiàn)了,如何獲取高清大圖的URL地址呢?

          如上圖所示,可以依次點擊URL地址,點擊進去之后就會發(fā)現(xiàn)里面的都是高清大圖的美女圖片了。如下圖所示:

          那接下來就可以來看看json數(shù)據(jù)的URL和高清大圖的URL存在著什么樣的區(qū)別。

          json數(shù)據(jù)內(nèi)的URL
          http://p1-tt.byteimg.com/list/190x124/pgc-image/183b0a981cf04498958beb194613fe43

          高清大圖的URL
          https://p6-tt.byteimg.com/origin/pgc-image/183b0a981cf04498958beb194613fe43?from=pc

          通過觀察上面的兩個URL,其實區(qū)別也不是很大,只需要替換一些字符就可以了。

          功能需求與實現(xiàn)

          獲取json數(shù)據(jù)

          獲取json數(shù)據(jù)倒不是特別難,主要是構(gòu)造URL參數(shù),具體代碼如下所示:

          def?get_page(offset):
          ????global?headers
          ????headers?=?{
          ????????'cookie':?'tt_webid=6925326312953529869;?s_v_web_id=verify_kkqm44un_jaeWrYZ1_CnOS_4Xuz_BNoi_lE3QmTQ37uHC;?csrftoken=280e107c397cea753911229202dc0c3d;?ttcid=45904355bfa4470f9543c9cdeb94869f30;?tt_webid=6925326312953529869;?csrftoken=280e107c397cea753911229202dc0c3d;?__ac_signature=_02B4Z6wo00f01Coh3wgAAIDDmtAzwcHMKowqBduAAGqaWRSmr26jOpvMaDLR3MsdEfPZTRN9mxTbUMgGifTuVJdj6FgWrIu6yKXVS3Dsp.wz3Pxl9vgfeguqCWDdZ4ocFVxb4JgkNBJTefPR41;?__tasessionId=pyia55cn11612433914121;?MONITOR_WEB_ID=2264d055-a390-4e4b-9b1f-4a3e2a6ac47c;?tt_scid=pcBhM4miMb3tReqLN21gkwPxqHE92TFulL0hVtP4mdhm0UL1X0v0T1r158U8hVOua37f',
          ????????'referer':?'https://www.toutiao.com/search/?keyword=%E7%BE%8E%E5%A5%B3',
          ????????'user-agent':?'Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/87.0.4280.66?Safari/537.36',
          ????????'x-requested-with':?'XMLHttpRequest'
          ????}
          ????params?=?{
          ????????'aid':'24',
          ????????'app_name':'web_search',
          ????????'offset':offset,
          ????????'format':'json',
          ????????'keyword':'美女',
          ????????'autoload':'true',
          ????????'count':'20',
          ????????'en_qc':'1',
          ????????'cur_tab':'1',
          ????????'from':'search_tab',
          ????????'pd':'synthesis',
          ????????'timestamp':int(time.time())
          ????}
          ????url?=?'https://www.toutiao.com/api/search/content/?'
          ????try:
          ????????response?=?requests.get(url,?headers=headers,?params=params)
          ????????response.content.decode('utf-8')
          ????????if?response.status_code?==?200:
          ????????????return?response.json()
          ????except?requests.ConnectionError?as?e:
          ????????print('連接失敗',?e)

          獲取圖片地址

          經(jīng)過上面的分析發(fā)現(xiàn),json內(nèi)部的圖片鏈接并不是高清大圖,所以在這里需要獲取高清大圖時需要做簡單的字符串替換。

          具體代碼如下所示:

          def?get_info(json):
          ????new_img_lists?=?[]
          ????image_lists?=?jsonpath.jsonpath(json,?'$.data[*].image_list..url')
          ????for?image_list?in?image_lists:
          ????????new_img_list?=?image_list.replace('p1',?'p6').replace('p3',?'p6').replace('list','origin').replace('/190x124',?'')
          ????????new_img_lists.append(new_img_list)
          ????return?new_img_lists

          保存圖片

          保存圖片的時候只需要向上面獲取到的圖片地址依次發(fā)送請求即可。具體代碼如下所示:

          def?save_img(new_image_lists):
          ????global?name
          ????for?image?in?new_image_lists:
          ????????print('-------正在獲取第{}張----------'.format(name))
          ????????data?=?requests.get(image,?headers=headers).content
          ????????with?open(f'../image/{name}.jpg',?'wb')?as?f:
          ????????????f.write(data)
          ????????name?+=?1

          結(jié)果展示

          關(guān)于翻頁

          其實翻頁問題相當(dāng)?shù)暮媒鉀Q,通過對上面Ajax的接口就可以發(fā)現(xiàn)offset其實就是實現(xiàn)翻頁效果的參數(shù),每一次都是20的倍數(shù),因此只需要傳遞offset的偏移量即可。

          具體代碼如下所示:

          def?main(offset):
          ????json?=?get_page(offset)
          ????#?print(type(json))
          ????new_image_lists?=?get_info(json)
          ????save_img(new_image_lists)


          if?__name__?==?'__main__':
          ????pool?=?Pool()
          ????groups?=?[i?*?20?for?i?in?range(4)]?#?0?20?40
          ????pool.map(main,?groups)?#?傳遞偏移量
          ????pool.close()
          ????pool.join()

          最后結(jié)果

          通過上圖以及代碼可以知道,我只傳遞了3個偏移量,就獲取到了229張的美女圖片。

          以上就是今天分享的所有內(nèi)容了。

          本篇文章告訴了大家:什么是Ajax?、如何查看與過濾Ajax請求。希望各位小伙伴以后遇到類似的問題可以舉一反三,加強練習(xí)。

          最后

          來自啃書君警告

          美女雖好,切莫貪杯,要是自己的ip被封了就得不償失了。

          啃書君說

          沒有一件事是可以一蹴而就的,哪有什么三天速成,七天速成,沒有堅持何來成功!生活如此,學(xué)習(xí)亦是如此!

          文章的每一個字,都是我用心敲出來的,只希望對得起每一位關(guān)注我的人。

          在文章末尾點個【贊】在看】,讓我知道,你們也在為自己的學(xué)習(xí)拼搏和努力著。

          掃一掃下面的二維碼,加我一起交流哦(拉你加Python交流群)~

          “掃一掃加我”

          瀏覽 47
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美高清无码 | 一级黄色片视频欧美 | 超清无码| 欧美爱爱视频免费看 | 欧美国产A片 |