# 使用Python爬取公眾號的合集 # 前言 。。。最近老是更新關於博客的文章,很久沒更新其他的了,然後寫一下如何爬取微信公眾號裡面的圖片吧! 先看看微信公眾號的樣子吧: 找到文章請求,然後就能獲取到。
# 設置請求參數
url = 'https://mp.weixin.qq.com/mp/appmsgalbum'
# 設置請求參數
params = {
'action': 'getalbum',
'__biz': 'MzDg3MjY3g==',
'album_id': '2646021169516584499',
'count': 10,
'is_reverse': 1, # 為倒敘也就是從第一篇文章開始
'uin': '',
'key': '',
'pass_ticket': '',
'wxtoken': '',
'devicetype': '',
'clientversion': '',
'__biz': 'MzDg3MjY3g==',
'appmsg_token': '',
'x5': 0,
'f': 'json'
}
# 設置請求頭
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
'Referer': '',
'Host': 'mp.weixin.qq.com',
'Accept-Encoding': 'gzip, deflate',
'Cookie': ''
}
分段展示代碼
# 設置請求頻率限制
MAX_REQUESTS_PER_MINUTE = 10
REQUEST_INTERVAL = 60 / MAX_REQUESTS_PER_MINUTE
# 發送請求,獲取第一頁相冊內容
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
data = json.loads(response.text)
album = data['getalbum_resp']['article_list']
last_msgid = album[-1]['msgid'] # 獲取最後一張圖片的消息ID 用作下次請求的begin_msgid
else:
print('獲取相冊內容失敗:', response.status_code)
# 迴圈發送請求,獲取所有相冊內容
result = []
while True:
params['begin_msgid'] = last_msgid
params['begin_itemidx'] = 1
print(url)
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
data = json.loads(response.text)
album = data['getalbum_resp']['article_list']
if len(album) == 0:
break # 如果相冊為空,則退出迴圈
for photo in album:
# 獲取url和title
url2 = photo['url']
title = photo['title']
result.append({'url': url2, 'title': title})
# 保存到csv文件中
with open('blogimg3.csv', 'a', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['url', 'title'])
writer.writerow({'url': url2, 'title': title})
# 控制請求頻率
time.sleep(REQUEST_INTERVAL)
last_msgid = album[-1]['msgid'] # 獲取最後一張圖片的消息ID,用於下一次請求
else:
print('獲取相冊內容失敗:', response.status_code)
break
ok 然後坐等爬取完成,我這裡是做了請求限制了的,如果想爬快一點把限制刪掉就行了。
文章爬取結果
也是爬取完成了,但是爬完之後會報KeyError: 'article_list'
的錯誤,這個無關緊要,因為已經請求到最後數據之後的請求了,導致獲取不到這個article_list的json數據了。
然後看到上面的圖片是254個內容,但是爬取的鏈接只有244條,數據缺失了幾條,但是程式也沒出現問題,所以就不管了,也就幾條數據,不影響,畢竟找出問題得花大量的時間。
爬取圖片
上面只是爬取了文章的url,現在要進入文章爬取圖片了。
首先,需要用到的庫
import csv
import requests
from lxml import etree
import os
from urllib.parse import urlparse
import time
然後爬取圖片的思路就是解析我們之前爬取的文章url,通過遍歷文章url,去使用xpath去匹配文章裡面的圖片就行了,第一次爬取出現了點小問題,後面會講。
關於Xpath獲取
偷懶方式如下:
匹配圖片url函數 download_images
def download_images(url):
# 設置請求頭
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
'Referer': '',
'Host': 'mp.weixin.qq.com',
'Accept-Encoding': 'gzip, deflate',
'Cookie': ''
}
# 發送請求
response = requests.get(url, headers=headers)
# 解析HTML
html = etree.HTML(response.text)
# 獲取圖片
img_elements = html.xpath('//*[@id="js_content"]/section/section[4]/p/img/@data-src')
if len(img_elements) == 0:
img_elements = html.xpath('//*[@id="js_content"]/section/section[4]/p/span/img/@data-src')
print(img_elements)
# 下載圖片
for url in img_elements:
print(f"下載圖片:{url}")
download_image(url, 'blogimg4_1')
**下載圖片函數 **download_image
# 下載
def download_image(url, img_dir):
# 解析url
parsed_url = urlparse(url).path
wx_fmt = parsed_url.split('/')[1].split('_')[1]
# 獲取文件名
filename = url.split('/')[-2] + '.' + wx_fmt
# 發送請求
response = requests.get(url)
# 保存圖片
with open(os.path.join(img_dir, filename), 'wb') as f:
f.write(response.content)
main方法
if __name__ == '__main__':
with open('blogimg3_1.csv',newline='',encoding='utf-8') as f:
# 讀取csv文件內容
reader = csv.reader(f)
# 遍歷每一行
for row in reader:
# 提取第一列的url
url = row[0]
# 發送請求
try:
download_images(url)
except Exception as e:
print(f'Error: {e}')
continue
time.sleep(2)
圖片爬取結果
可以看到有個別圖片沒有正常顯示,那是因為這個公眾號最新的文章圖片url和之前不一樣,我也是爬完才發現,雖然才幾張圖片,但是得優化一下
第一次爬取,爬到了1333張圖片
優化下載圖片代碼
download_image函數:
# 解析url
parsed_url = urlparse(url)
path_parts = parsed_url.path.split('/')
# 判斷鏈接特征並提取參數值
if 'wx_fmt' in parsed_url.query:
wx_fmt = parsed_url.query.split('=')[1]
# 獲取文件名
filename = path_parts[-2] + '.' + wx_fmt
elif 'mmbiz_jpg' in path_parts:
filename = os.path.splitext(path_parts[2])[0] + '.jpg'
elif 'mmbiz_png' in path_parts:
filename = os.path.splitext(path_parts[2])[0] + '.png'
# 發送請求
response = requests.get(url)
# 保存圖片
with open(os.path.join(img_dir, filename), 'wb') as f:
f.write(response.content)
優化之後也是沒有出現圖片無法顯示的情況,然後爬取了1368張圖片。
聲明
文章出現的代碼只用於學習,不會影響公眾號正常運行,如有侵權,聯繫站長刪除。
爬取下來的圖片將不會保存,望知~
QQ郵箱:[email protected]
結尾
公眾號是沒有反爬機制的,所以爬取下來很容易,不過公眾號放的圖片都不夠高清,但是也還是能看。如果也想學習學習如何爬取的,可以關註公眾號私信我,找我要鏈接。如果有更好的圖片網站,也可以私信我~