50行程式碼教你打造一個公眾號文章採集器
Alfred的女票是一枚資料科學領域的新媒體運營官(是的,Alfred是一名程式設計師,Alfred有女票),每天都要閱讀大量的行業相關文章,以掌握行業的動向,挑選和生產相關內容。為此,她關注了一大批的相關公眾號,每天都一個個公眾號挨個點開閱讀,怪麻煩的。
一來可能漏掉某些公眾號更新的重要訊息,二來經常會看到轉載的重複性的文章。
這可咋辦呢?
身為一個合(gao)格(shi)的男票,我是那個看在眼裡急在心裡啊!
那就寫一個公眾號文章的收集器吧,每天早上9點的時候都把昨天一天以來各個行業內公眾號發表的文章的標題、摘要和連結等相關資訊爬下來,形成一個文件發給女票,這樣可以大大方便閱讀。
就這麼愉快地決定了
需求很簡單,主要分為兩塊,一塊是公眾號文章爬取,一塊是把爬回來的文章儲存為word文件。
公眾號文章爬取
首先跟女票要了她關注的公眾號,結果她發我很長很長的一串列表,足足有50多個公眾號。算了算,如果每個公眾號每天更新3篇文章,那麼她每天最少就得看150多篇公眾號文章,確實是夠嗆呀。
接著是爬取公眾號文章。這方面早已有人造好了輪子,也就是基於搜狗微信搜尋的微信公眾號爬蟲介面:WechatSogou,在此感謝@Chyroc。
傳送門:
https://github.com/Chyroc/WechatSogou
也就是,我們不用自己造輪子,只需要呼叫API就好了。
wechatsogou 的使用很簡單,先例項化一個WechatSogouAPI,便可以呼叫get_gzh_article_by_history()方法返回最近10篇文章,比如說要爬取“Alfred在紐西蘭”的文章,便是:
ws_api = wechatsogou.WechatSogouAPI()
ws_api. get_gzh_article_by_history('Alfred在紐西蘭')
這樣便可以返回一個json檔案,裡面包含“Alfred在紐西蘭”公眾號的最近10篇文章。
這個輪子是不是嗖嗖的?
可見,文章儲存在“article”對應的列表裡,相關的資訊有標題(title)、摘要(abstract)、文章連結(content_url)、發表時間(datetime)、是否頭條(main)、版權狀況(copyright_stat)等。
這就是說,只要例項化一個WechatSogouAPI,然後遍歷一下長長的公眾號列表,便可以把所有公眾號近期發表的文章爬取下來了。然後加一個時間過濾,便可獲得一天以來發表的文章。
當然,作為一個貼心的男票,我還加上了頭條文章過濾和原創文章過濾,預設把不是頭條和不是原創的文章都過濾掉,並把它封裝成一個function:
from datetime import *
import wechatsogou
# 文章爬取
def get_articles(headline=True, original=True, timedel=1, add_account=None):
with open('gzh.txt', 'r') as f:
accounts = [account.strip() for account in f.readlines()]
# add_account必須是一個list或None
if add_account is not None:
if isinstance(list, add_account):
accounts.extend(add_account)
with open('gzh.txt', 'w') as f:
for account in accounts:
f.write(account)
else:
print('add_account should be a list')
ws_api = wechatsogou.WechatSogouAPI(captcha_break_time=3)
articles = []
for account in accounts:
articles.extend(reformat(ws_api.get_gzh_article_by_history(account)))
# 時間過濾,只選取規定天數以內的
timestamp = int((datetime.now()-timedelta(days=timedel)).timestamp())
articles = [article for article in articles if article['datetime'] > timestamp]
# 頭條文章過濾,是否選取頭條文章,預設是
if headline:
articles = [article for article in articles if article['main'] == 1]
# 原創文章過濾,是否選取原創文章,預設是
if original:
articles = [article for article in articles if article['copyright_stat'] == 100]
return articles
# 為儲存每篇文章的字典新增一個公眾號來源
def reformat(data):
atcs = data.get('article')
if atcs is not None:
wechat_name = data.get('gzh')['wechat_name']
for article in atcs:
article['wechat_name'] = wechat_name
return atcs
儲存為word文件
最後爬回來的文章是一個list,裡面每個dict存放著每篇文章的資訊。我們需要把這個list儲存到word文件裡面,並且以一個清晰的排版呈現出來。
這時候有一個叫python-docx的庫,可以很方便的幫助我們來做這件事情。
傳送門:
https://python-docx.readthedocs.io/
Python-docx的使用也很簡單,例項化一個類,再通過add_headingd()的方法新增標題、add_paragraph()方法新增段落、add_picture()方法新增圖片,便可以按照我們的想法進行排版。例如:
from docx import Document
from docx.shared import Inches
document = Document() # 例項化一個Document類
document.add_heading('這是一個標題', 0) # 新增標題
document.add_paragraph('這是一段話') # 新增段落
document.add_picture('一個圖片.jpeg', width=Inches(1)) 新增圖片
上面一段程式碼生成的word文件長這樣:
因此,遍歷一下爬回來的list,然後排版,儲存到本地,便大功告成了。
最後爬回來的文件開頭長這樣:
結尾長這樣:
撒狗糧成功!溜了~
後記:
1.後期還可以為這個採集器加上更多的功能,比如說再新增一個把word以郵件形式直接傳送郵箱的功能,或者儲存為Excel的功能等,都是可以的;
2.當然也可以把它轉換成小程式,方便執行;
3.由於驗證碼識別的原因,有一些驗證碼需要人工識別,希望以後的wechatsougou可以更強大;
4.完整的程式碼可以在公眾號後臺回覆"公眾號文章"獲取。
∞∞∞∞∞
IT派 - {技術青年圈}持續關注網際網路、區塊鏈、人工智慧領域公眾號回覆“Python”,
邀你加入{ IT派Python技術群 }