Python爬蟲入門教程 7-100 蜂鳥網圖片爬取之二

来源:https://www.cnblogs.com/happymeng/archive/2018/12/19/10141143.html
-Advertisement-
Play Games

簡介 今天玩點新鮮的,使用一個新庫 ,利用它提高咱爬蟲的爬取速度。 安裝模塊常規套路 pip install aiohttp 運行之後等待,安裝完畢,想要深造,那麼官方文檔必備 : "https://aiohttp.readthedocs.io/en/stable/" 接下來就可以開始寫代碼了。 我 ...


簡介

今天玩點新鮮的,使用一個新庫 aiohttp ,利用它提高咱爬蟲的爬取速度。

安裝模塊常規套路

pip install aiohttp

在這裡插入圖片描述

運行之後等待,安裝完畢,想要深造,那麼官方文檔必備 :https://aiohttp.readthedocs.io/en/stable/

接下來就可以開始寫代碼了。

我們要爬取的頁面,這一次選取的是

http://bbs.fengniao.com/forum/forum_101_1_lastpost.html

打開頁面,我們很容易就獲取到了頁碼

在這裡插入圖片描述
好久沒有這麼方便的看到頁碼了。




嘗試用 aiohttp 訪問這個頁面吧,模塊的引入,沒有什麼特殊的,採用 import 即可
如果我們需要 使用Asyncio + Aiohttp非同步IO 編寫爬蟲,那麼需要註意,你需要非同步的方法前面加上async

接下來,先嘗試去獲取一下上面那個地址的網頁源碼。

代碼中,先聲明一個fetch_img_url的函數,同時攜帶一個參數,這個參數也可以直接寫死。

with 上下文不在提示,自行搜索相關資料即可 (`・ω・´)

aiohttp.ClientSession() as session: 創建一個session對象,然後用該session對象去打開網頁。session可以進行多項操作,比如post, get, put

代碼中 await response.text() 等待網頁數據返回

asyncio.get_event_loop創建線程,run_until_complete方法負責安排執行 tasks中的任務。tasks可以為單獨的函數,也可以是列表。

import aiohttp  
import asyncio 


async def fetch_img_url(num):
    url = f'http://bbs.fengniao.com/forum/forum_101_{num}_lastpost.html'  # 字元串拼接
    # 或者直接寫成 url = 'http://bbs.fengniao.com/forum/forum_101_1_lastpost.html'
    print(url)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6726.400 QQBrowser/10.2.2265.400',
    }

    async with aiohttp.ClientSession() as session:
        # 獲取輪播圖地址
        async with session.get(url,headers=headers) as response:
            try:
                html = await response.text()   # 獲取到網頁源碼
                print(html)
                
            except Exception as e:
                print("基本錯誤")
                print(e)

# 這部分你可以直接臨摹
loop = asyncio.get_event_loop()
tasks = asyncio.ensure_future(fetch_img_url(1))
results = loop.run_until_complete(tasks)

上面代碼最後一部分也可以寫成

loop = asyncio.get_event_loop()
tasks =  [fetch_img_url(1)]
results = loop.run_until_complete(asyncio.wait(tasks))

好了,如果你已經成果的獲取到了源碼,那麼距離最終的目的就差那麼一丟丟了。
修改代碼為批量獲取10頁。
只需要修改tasks即可,在此運行,看到如下結果

tasks =  [fetch_img_url(num) for num in range(1, 10)]

在這裡插入圖片描述

下麵的一系列操作和上一篇博客非常類似,找規律。
隨便打開一個頁面

http://bbs.fengniao.com/forum/forum_101_4_lastpost.html

點擊一張圖片,進入內頁,在點擊內頁的一張圖片,進入到一個輪播頁面
在這裡插入圖片描述

再次點擊進入圖片播放頁面

在這裡插入圖片描述

最後我們在圖片播放頁面,找到源碼中發現了所有的圖片鏈接,那麼問題出來了,如何從上面的第一個鏈接,轉變成輪播圖的鏈接???
下麵的源碼是在 http://bbs.fengniao.com/forum/pic/slide_101_10408464_89383854.html 右鍵查看源碼。
在這裡插入圖片描述

繼續分析吧~~~~ ヾ(=・ω・=)o

http://bbs.fengniao.com/forum/forum_101_4_lastpost.html
轉變成下麵的鏈接?
http://bbs.fengniao.com/forum/pic/slide_101_10408464_89383854.html

繼續看第一個鏈接,我們使用F12開發者工具,去抓取一個圖片看看。

在這裡插入圖片描述

圖片中標黃色框的位置,發現了我們想要的數字,那麼好了,我們只需要通過正則表達式把他們匹配出來就好了。
代碼在下麵####的位置,需要註意的是,我採用的原始的正則匹配,在編寫正則表達式的過程中,我發現一步竟然沒有完整匹配,只能分成兩個步驟了,你可以看一下具體的細節o(╥﹏╥)o

  1. 查找所有的圖片<div class="picList">
  2. 獲取我們想要的兩部分數字
async def fetch_img_url(num):
    url = f'http://bbs.fengniao.com/forum/forum_101_{num}_lastpost.html'
    print(url)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6726.400 QQBrowser/10.2.2265.400',
    }

    async with aiohttp.ClientSession() as session:
        # 獲取輪播圖地址
        async with session.get(url,headers=headers) as response:
            try:
                ###############################################
                url_format = "http://bbs.fengniao.com/forum/pic/slide_101_{0}_{1}.html"
                html = await response.text()   # 獲取到網頁源碼
                pattern = re.compile('<div class="picList">([\s\S.]*?)</div>')
                first_match = pattern.findall(html)
                href_pattern = re.compile('href="/forum/(\d+?)_p(\d+?)\.html')
                urls = [url_format.format(href_pattern.search(url).group(1), href_pattern.search(url).group(2)) for url in first_match]
                ##############################################

            except Exception as e:
                print("基本錯誤")
                print(e)

代碼完成,我們已經獲取到,我們想要的URL了,下麵繼續讀取URL內部信息,然後匹配我們想要的圖片鏈接

async def fetch_img_url(num):
    # 去抄上面的代碼
    async with aiohttp.ClientSession() as session:
        # 獲取輪播圖地址
        async with session.get(url,headers=headers) as response:
            try:
                #去抄上面的代碼去吧
                ################################################################
                for img_slider in urls:
                    try:
                        async with session.get(img_slider, headers=headers) as slider:
                            slider_html = await slider.text()   # 獲取到網頁源碼
                            try:
                                pic_list_pattern = re.compile('var picList = \[(.*)?\];')
                                pic_list = "[{}]".format(pic_list_pattern.search(slider_html).group(1))
                                pic_json = json.loads(pic_list)  # 圖片列表已經拿到
                                print(pic_json)
                            except Exception as e:
                                print("代碼調試錯誤")
                                print(pic_list)
                                print("*"*100)
                                print(e)

                    except Exception as e:
                        print("獲取圖片列表錯誤")
                        print(img_slider)
                        print(e)
                        continue
                ################################################################


                print("{}已經操作完畢".format(url))
            except Exception as e:
                print("基本錯誤")
                print(e)

在這裡插入圖片描述

圖片最終的JSON已經拿到,最後一步,下載圖片,噹噹當~~~~,一頓迅猛的操作之後,圖片就拿下來了


async def fetch_img_url(num):
    # 代碼去上面找
    async with aiohttp.ClientSession() as session:
        # 獲取輪播圖地址
        async with session.get(url,headers=headers) as response:
            try:
                # 代碼去上面找
                for img_slider in urls:
                    try:
                        async with session.get(img_slider, headers=headers) as slider:
                            # 代碼去上面找
                            ##########################################################
                            for img in pic_json:
                                try:
                                    img = img["downloadPic"]
                                    async with session.get(img, headers=headers) as img_res:
                                        imgcode = await img_res.read()  # 圖片讀取
                                        with open("images/{}".format(img.split('/')[-1]), 'wb') as f:
                                            f.write(imgcode)
                                            f.close()
                                except Exception as e:
                                    print("圖片下載錯誤")
                                    print(e)
                                    continue
                            ###############################################################

                    except Exception as e:
                        print("獲取圖片列表錯誤")
                        print(img_slider)
                        print(e)
                        continue
                print("{}已經操作完畢".format(url))
            except Exception as e:
                print("基本錯誤")
                print(e)

圖片會在你提前寫好的images文件夾裡面快速的生成
在這裡插入圖片描述

tasks最多可以開1024協程,但是建議你開100個就OK了,太多併發,人家伺服器吃不消。

以上操作執行完畢,在添加一些細節,比如保存到指定文件夾,就OK了。

github代碼地址


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • java深克隆和淺克隆 基本概念 1. 被覆制對象的所有變數都含有與原來的對象相同的值,而所有的對其他對象的引用仍然指向原來的對象。換言之,淺複製僅僅複製所拷貝的對象,而不複製它所引用的對象。 1. 被覆制對象的所有變數都含有與原來的對象相同的值,除去那些引用其他對象的變數。那些引用其他對象的變數將 ...
  • 轉載請標明出處: https://www.fangzhipeng.com 本文出自 "方誌朋的博客" 在上一篇文章詳細的介紹了Gateway的Predict,Predict決定了請求由哪一個路由處理,在路由處理之前,需要經過“pre”類型的過濾器處理,處理返迴響應之後,可以由“post”類型的過濾器 ...
  • 一、適配器模式 1、概念 定義:將一個類的介面,轉換成客戶期望的另一個類的介面,適配器讓原本介面不相容的類可以合作無間。 安卓轉Type C頭,就是一個典型的適配器模式。在安卓頭和 Type C 之間引入適配器,安卓頭是被適配者。 解析:   1、 客戶(Client)通過目標接 ...
  • Zookeeper 的核心原理 Zookeeper 的由來 各個節點的數據一致性 怎麼保證任務只在一個節點執行 如果orderserver1掛了,其他節點如何發現並接替 存在共用資源,互斥性、安全性 Apache 的Zookeeper Google 的Chubby 是一個分散式鎖服務,通過Googl ...
  • 中介者模式是一種常見的解耦思維的模式,本文對中介者模式進行了簡單介紹,給出了中介者模式的意圖,結構,以及意圖發展演變,給出了中介者模式的Java代碼示例,中介者模式又稱為調停者模式,是迪米特法則的詮釋。 ...
  • 公眾號:SAP Technical 本文作者:matinal 原文出處:http://www.cnblogs.com/SAPmatinal/ 原文鏈接:SAP ABAP7.5x系列之預定義數據結構 前言部分 先說一下,之前有些文章被轉載之後也沒有註明,這個就比較不好。如果你覺得本文寫的並不好,那麼可 ...
  • 整體思路: 1.用戶功能:購買、顯示餘額、列表清單、輸入 2.商家功能:修改和添加商品 創建兩個介面: 用戶: 商家: ...
  • c: #include<stdio.h>//從大到小 int main(){ int a, b, c; int x = 0; printf("input message:\n"); scanf("%d %d %d", &a, &b, &c); if(a < b) { x = a; a = b; b ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...