搜狗微信搜尋提供兩種型別的關鍵詞搜尋,一種是搜尋公眾號文章內容,另一種是直接搜尋微信公眾號。通過微信公眾號搜尋可以獲取公眾號的基本資訊及最近釋出的10條文章,之前寫過一篇《Python 抓取微信公眾號文章》,今天來抓取一下微信公眾號的賬號資訊(→ 先看結果(2998條) ←)。
爬蟲
首先通過首頁進入,可以按照類別抓取,通過“檢視更多”可以找出頁面連結規則:
import requests as req
import re
reTypes = r'id="pc_\d*" uigs="(pc_\d*)">([\s\S]*?)</a>'
Entry = "http://weixin.sogou.com/"
entryPage = req.get(Entry)
allTypes = re.findall(reTypes, getUTF8(entryPage))
for (pcid, category) in allTypes:
for page in range(1, 100):
url = 'http://weixin.sogou.com/pcindex/pc/{}/{}.html'.format(pcid, page)
print(url)
categoryList = req.get(url)
if categoryList.status_code != 200:
break複製程式碼
上面程式碼通過載入更多頁面獲取載入列表,進而從其中抓取微信公眾號詳情頁面:
reProfile = r'<li id[\s\S]*?<a href="([\s\S]*?)"'
allProfiles = re.findall(reOAProfile, getUTF8(categoryList))
for profile in allProfiles:
profilePage = req.get(profile)
if profilePage.status_code != 200:
continue複製程式碼
進入詳情頁面可以獲取公眾號的名稱/ID/功能介紹/賬號主體/頭像/二維碼/最近10篇文章
等資訊:
注意事項
詳情頁面連結:
http://mp.weixin.qq.com/profile?src=3×tamp=1477208282&ver=1&signature=8rYJ4QV2w5FXSOy6vGn37sUdcSLa8uoyHv3Ft7CrhZhB4wO-bbWG94aUCNexyB7lqRNSazua-2MROwkV835ilg==
1. 驗證碼
訪問詳情頁面時有可能需要驗證碼,自動識別驗證碼還是很有難度的,因此要做好爬蟲的偽裝工作。
2. 未儲存詳情頁面連結
詳情頁面的連結中有兩個重要引數:timestamp & signature
,這說明頁面連結是有時效性的,所以儲存下來應該也沒用;
3. 二維碼
二維碼圖片連結同樣具有時效性,因此如需要最好將圖片下載下來。
用 Flask 展示結果
最近 Python 社群出現了一款非同步增強版的 Flask 框架:Sanic,基於uvloop和httptools,可以達到非同步、更快的效果,但保持了與 Flask 一致的簡潔語法。雖然專案剛起步,還有很多基本功能為實現,但已經獲得了很多關注(2,222 Star)。這次本打算用抓取的微信公眾號資訊基於 Sanic 做一個簡單的互動應用,但無奈目前還沒有加入模板功能,非同步的 redis 驅動也還有 BUG 沒解決,所以簡單嘗試了一下之後還是切換回 Flask + SQLite,先把抓取結果呈現出來,後續有機會再做更新。
安裝 Sanic
Debug Sanic
Flask + SQLite App
from flask import g, Flask, render_template
import sqlite3
app = Flask(__name__)
DATABASE = "./db/wx.db"
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(DATABASE)
return db
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
@app.route("/<int:page>")
@app.route("/")
def hello(page=0):
cur = get_db().cursor()
cur.execute("SELECT * FROM wxoa LIMIT 30 OFFSET ?", (page*30, ))
rows = []
for row in cur.fetchall():
rows.append(row)
return render_template("app.html", wx=rows, cp=page)
if __name__ == "__main__":
app.run(debug=True, port=8000)複製程式碼
【檢視原文】