首頁 >後端開發 >Python教學 >Scrapy實現微信公眾號文章爬取與分析

Scrapy實現微信公眾號文章爬取與分析

WBOY
WBOY原創
2023-06-22 09:41:241914瀏覽

Scrapy實現微信公眾號文章爬取和分析

微信是近年來備受歡迎的社群媒體應用,在其中運作的公眾號也扮演著非常重要的角色。眾所周知,微信公眾號是一個資訊和知識的海洋,因為其中每個公眾號都可以發布文章、圖文訊息等資訊。這些資訊可以被廣泛地應用在許多領域中,例如媒體報道、學術研究等。

那麼,這篇文章將介紹如何使用Scrapy框架來實現微信公眾號文章的爬取與分析。 Scrapy是一個Python的網路爬蟲框架,主要功能是進行資料探勘和資訊查找。因此,Scrapy具有很好的可自訂性和高效性。

  1. 安裝Scrapy並建立專案

要使用Scrapy框架進行爬蟲,首先需要安裝Scrapy和其他相依性。可以使用pip指令進行安裝,安裝過程如下所示:

pip install scrapy
pip install pymongo
pip install mysql-connector-python

安裝Scrapy之後,我們需要使用Scrapy命令列工具來建立專案。指令如下:

scrapy startproject wechat

執行指令後,Scrapy將會建立一個名為「wechat」的項目,並在專案目錄中建立許多檔案和目錄。

  1. 實作微信公眾號文章的爬取

在我們開始爬蟲之前,我們需要先搞懂微信公眾號文章頁的URL格式。一個典型的微信公眾號文章頁面的URL長這樣:

https://mp.weixin.qq.com/s?__biz=XXX&mid=XXX&idx=1&sn=XXX&chksm=XXX#wechat_redirect

其中,__biz 表示微信公眾號的ID,mid 表示文章的ID,idx 表示文章的序號,sn 表示文章的簽名,chksm 表示內容校驗。因此,如果我們要爬取某個公眾號的所有文章,就需要找到這個公眾號的ID,並用它來建構URL。其中,biz_id 是該公眾號的唯一識別。

首先,我們需要準備一個包含許多公眾號ID的列表,因為我們要爬取這些公眾號的文章。而ID的蒐集可以透過各種手段來實現。在這裡,我們使用一個包含幾個測試ID的列表作為例子:

biz_ids = ['MzU5MjcwMzA4MA==', 'MzI4MzMwNDgwMQ==', 'MzAxMTcyMzg2MA==']

#接著,我們需要寫一個Spider,來爬取某個公眾號的所有文章。這裡,我們將公眾號碼的名字和ID傳遞到Spider,以方便我們可以處理不同的公眾號碼ID。

import scrapy
import re

class WeChatSpider(scrapy.Spider):
    name = "wechat"
    allowed_domains = ["mp.weixin.qq.com"]
    
    def __init__(self, name=None, biz_id=None):
        super().__init__(name=name)
        self.start_urls = ['https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz={}==#wechat_redirect'.format(biz_id)]

    def parse(self, response):
        article_urls = response.xpath('//h4[1]/a/@href')
        for url in article_urls.extract():
            yield scrapy.Request(url, callback=self.parse_article)
        
        next_page = response.xpath('//a[@id="js_next"]/@href')
        if next_page:
            yield scrapy.Request(response.urljoin(next_page[0].extract()), callback=self.parse)
    
    def parse_article(self, response):
        url = response.url
        title = response.xpath('//h2[@class="rich_media_title"]/text()')
        yield {'url': url, 'title': title.extract_first().strip()}

Spider的主要功能是使用給定的公眾號ID來存取公眾號首頁,然後遞歸地遍歷每一頁,提取所有文章的URL。此外,parse_article方法用於提取文章的URL和標題,以進行後續處理。總體而言,該Spider不是很複雜,但是提取速度較慢。

最後,我們需要在Terminal中輸入下面的命令來啟動Spider:

scrapy crawl wechat -a biz_id=XXXXXXXX

同樣,我們也可以爬取多個公眾號,只需要在命令中指定所有公眾號的ID即可:

scrapy crawl wechat -a biz_id=ID1,ID2,ID3
  1. 儲存文章資料

爬取文章之後,我們需要將文章的標題和URL儲存到資料庫(如MongoDB、MySQL等)。在這裡,我們將使用pymongo函式庫來保存爬取到的資料。

import pymongo

class MongoPipeline(object):
    collection_name = 'wechat'

    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri=crawler.settings.get('MONGO_URI'),
            mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
        )

    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    def close_spider(self, spider):
        self.client.close()

    def process_item(self, item, spider):
        self.db[self.collection_name].insert_one(dict(item))
        return item

在該Pipeline中,我們使用了MongoDB作為儲存資料的後端。可以根據需要修改這個類別來使用其他的資料庫系統。

接下來,我們需要在settings.py檔案中配置資料庫相關的參數:

MONGO_URI = 'mongodb://localhost:27017/'
MONGO_DATABASE = 'wechat'
ITEM_PIPELINES = {'myproject.pipelines.MongoPipeline': 300}

最後,我們在Spider中呼叫Pipeline,以將資料儲存到MongoDB中:

class WeChatSpider(scrapy.Spider):
    name = "wechat"
    allowed_domains = ["mp.weixin.qq.com"]
    
    def __init__(self, name=None, biz_id=None):
        super().__init__(name=name)
        self.start_urls = ['https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz={}==#wechat_redirect'.format(biz_id)]

    def parse(self, response):
        article_urls = response.xpath('//h4[1]/a/@href')
        for url in article_urls.extract():
            yield scrapy.Request(url, callback=self.parse_article)
        
        next_page = response.xpath('//a[@id="js_next"]/@href')
        if next_page:
            yield scrapy.Request(response.urljoin(next_page[0].extract()), callback=self.parse)
            
    def parse_article(self, response):
        url = response.url
        title = response.xpath('//h2[@class="rich_media_title"]/text()')
        yield {'url': url, 'title': title.extract_first().strip()}

        pipeline = response.meta.get('pipeline')
        if pipeline:
            item = dict()
            item['url'] = url
            item['title'] = title.extract_first().strip()
            yield item

在上面的程式碼中,response.meta.get('pipeline')是用來取得我們在Spider中設定的Pipeline的物件的。因此,只需在Spider程式碼中加入以下程式碼,就可以支援Pipeline了:

yield scrapy.Request(url, callback=self.parse_article, meta={'pipeline': 1})
  1. #資料分析

最後,我們將使用Scrapy和pandas等函式庫來實現數據的分析和視覺化。

在這裡,我們將從MongoDB中提取我們爬取到的數據,並將其保存到CSV檔案中。隨後,我們可以使用pandas來對CSV檔案進行處理,並進行視覺化。

以下是實作過程:

import pandas as pd
from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')
db = client['wechat']
articles = db['wechat']

cursor = articles.find()
doc = list(cursor)

df = pd.DataFrame(doc)
df.to_csv('wechat.csv', encoding='utf-8')

df.groupby('biz_id')['title'].count().plot(kind='bar')

以上程式碼中,我們使用了 MongoDB 和 Pandas 函式庫來將爬取到的資料儲存到 CSV 檔案的 data 資料夾內。隨後,我們使用 Pandas 強大的數據分析功能將每個公眾號的文章數量進行了視覺化展示。

以上是Scrapy實現微信公眾號文章爬取與分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn