python爬取微信公众号文章(包含文章内容和图片) 您所在的位置:网站首页 55号图片 python爬取微信公众号文章(包含文章内容和图片)

python爬取微信公众号文章(包含文章内容和图片)

2024-07-17 10:41| 来源: 网络整理| 查看: 265

    之前虽然做过网页爬取,但微信爬取一直没做过,因为我一直不知道网页可以进微信公众平台,只用过微信客户端进微信公众号。既然可以通过网页进微信公众平台,那么爬取微信公众号文章就流程上就没太多难度了。

    自己在网上找的一些python爬虫文章不太好用,就亲自写了一套,包括详细的页面附图和代码注释,代码复制下来后可以直接运行,供需要的同行参考交流。  爬取微信公众号文章之前,需要先申请微信公众号,针对个人使用的订阅号就行。

    爬取微信公众号文章有两种思路:

   一种是通过搜狗浏览器爬取,因为微信公众平台为搜狗提供了访问接口。

  第二种种就是通过google或firefox浏览器来爬取,本篇文章只讲解第二种方式,但第一种方式也可以借鉴第二种方式的部分代码。

    1、通过调用谷歌或火狐浏览器驱动,模拟微信公众号登录,获取到cookies(里面包含登录身份的token值),将cookies保存到本地文件中,供以后面访问微信公众号时携带身份识别之用。

    页面如下:

 点击登录后跳出来扫描验证页面:

 

login.py文件代码如下:

# -!- coding: utf-8 -!- from selenium import webdriver import time import json #谷歌和火狐两种驱动人选一种即可 # 调用谷歌浏览器驱动 如果本地电脑未安装谷歌驱动,请网上下载 driver = webdriver.Chrome() # 调用火狐浏览器驱动 如果本地电脑未安装火狐驱动,请网上下载 # driver = webdriver.Firefox() driver.get("https://mp.weixin.qq.com/") # 微信公众平台网址 driver.find_element_by_link_text("使用帐号登录").click() # 此行代码为2020.10.10新增,因为微信公众号页码原来默认直接为登录框, 现在默认为二维码,此行代码可以将二维码切换到登录框页面 driver.find_element_by_name("account").clear() driver.find_element_by_name("account").send_keys("[email protected]") # 自己的微信公众号 time.sleep(2) driver.find_element_by_name("password").clear() driver.find_element_by_name("password").send_keys("*******") # 自己的微信公众号密码 driver.find_element_by_class_name("icon_checkbox").click() time.sleep(2) driver.find_element_by_class_name("btn_login").click() time.sleep(15) #此时会弹出扫码页面,需要微信扫码 cookies = driver.get_cookies() # 获取登录后的cookies print(cookies) cookie = {} for items in cookies: cookie[items.get("name")] = items.get("value") # 将cookies写入到本地文件,供以后程序访问公众号时携带作为身份识别用 with open('cookies.txt', "w") as file: # 写入转成字符串的字典 file.write(json.dumps(cookie))

    2、扫码后进入公众号首页,点击左侧的“图文素材”,在点击右侧的“图文模板”,如下图:

 

3、点击完“图文模板”后进入如下界面,并点击“新建图文模板”:

 

4、点击完“新建图文模板”后,等待5~6秒,进入如下页面:

 

5、点击上图中红色框处的“超链接”,进入如下页面,点击“选择其他公众号”,选择查找文章,在公众号中输入要查询的公众号,并点击输入框右侧的放大镜查询标识,例如输入“共轨之家”(别想歪了哈,只是个介绍汽车维修资料的公众号哈):

6、选中搜索出来的符合要求的公众号(当然也可以用微信公众号的唯一id搜,例如:gongguizhijia),单击后进入公众号,可以看到该公众号下的文章,如下图:

下拉到底部,可以看到页码:

7、此时要上代码了,先分析一下文章的分页和F12后可以看到的请求信息。

    (1)、我们看到总共53页,每页展示20条。

    (2)、F12查看请求方式,请求头如下图:

    (3)不断的点击不同页码,发现查询参数begin的值和页码的关系为:begin=(当前页-1)*5,count值始终为5,token值可以从浏览器中获取。

   8、爬取该公众号下的所有文章的名字、唯一表示、链接,保存到本地文件article_link中,供爬取文章页面用(此处微信有访问频率限制,具体多少没详细测,我连续访问32次后被限制访问,提醒我操作频繁)。

         get_article_link.py代码如下:

# -*- coding:utf-8 -*- import requests import json import re import random import time with open("cookies.txt", "r") as file: cookie = file.read() cookies = json.loads(cookie) url = "https://mp.weixin.qq.com" response = requests.get(url, cookies=cookies) token = re.findall(r'token=(\d+)', str(response.url))[0] # 从url中获取token print(token) headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36", "Referer": "https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit_v2&action=edit&isNew=1&type=10&token="+token+"&lang=zh_CN", "Host": "mp.weixin.qq.com", } # requestUrl = "https://mp.weixin.qq.com/cgi-bin/searchbiz" with open('article_link.txt', "w", encoding='utf-8') as file: for j in range(1, 53, 1): begin = (j-1)*5 requestUrl = "https://mp.weixin.qq.com/cgi-bin/appmsg?token="+token+"&lang=zh_CN&f=json&ajax=1&random="+str(random.random())\ +"&action=list_ex&begin="+str(begin)+"&count=5&query=&fakeid=MzA3NDM2ODIzMQ%3D%3D&type=9" search_response = requests.get(requestUrl, cookies=cookies, headers=headers) re_text = search_response.json() print(re_text) list = re_text.get("app_msg_list") for i in list: file.write(i["aid"]+""+i["title"]+""+i["link"] + "\n") print(i["aid"]+""+i["title"]+""+i["link"]) time.sleep(20)

9、获取到的链接保存格式为:

10、解析上一步获取到的文章链接,

download_article.py代码如下:

# -*- coding:utf-8 -*- import json import re import time from bs4 import BeautifulSoup import requests import os # 保存页面到本地 def save_html(url_content,htmlDir,file_name): f = open(htmlDir+"\\"+file_name+'.html', 'wb') f.write(url_content.content) # save to page.html f.close() return url_content # 修改文件,将图片路径改为本地的路径 def update_file(old, new,htmlDir): with open(htmlDir+"\\"+file_name+'.html', encoding='utf-8') as f, open(htmlDir+"\\"+file_name+'_bak.html', 'w', encoding='utf-8') as fw: # 打开两个文件,原始文件用来读,另一个文件将修改的内容写入 for line in f: # 遍历每行,取出来的是字符串,因此可以用replace 方法替换 new_line = line.replace(old, new) # 逐行替换 new_line = new_line.replace("data-src", "src") fw.write(new_line) # 写入新文件 os.remove(htmlDir+"\\"+file_name+'.html') # 删除原始文件 time.sleep(10) os.rename(htmlDir+"\\"+file_name+'_bak.html', htmlDir+"\\"+file_name+'.html') # 修改新文件名, old -> new print('当前保存文件为:'+file_name+'.html') # 保存图片到本地 def save_file_to_local(htmlDir,targetDir,search_response,domain): obj = BeautifulSoup(save_html(search_response,htmlDir,file_name).content, 'lxml') # 后面是指定使用lxml解析,lxml解析速度比较快,容错高。 imgs = obj.find_all('img') # 将页面上图片的链接加入list urls = [] for img in imgs: if 'data-src' in str(img): urls.append(img['data-src']) elif 'src=""' in str(img): pass elif "src" not in str(img): pass else: urls.append(img['src']) # 遍历所有图片链接,将图片保存到本地指定文件夹,图片名字用0,1,2... i = 0 for each_url in urls: # 看下文章的图片有哪些格式,一一处理 if each_url.startswith('//'): new_url = 'https:' + each_url r_pic = requests.get(new_url) elif each_url.startswith('/') and each_url.endswith('gif'): new_url = domain + each_url r_pic = requests.get(new_url) elif each_url.endswith('png') or each_url.endswith('jpg') or each_url.endswith('gif') or each_url.endswith('jpeg'): r_pic = requests.get(each_url) t = os.path.join(targetDir, str(i) + '.jpeg') # 指定目录 print('当前保存图片为:' + t) fw = open(t, 'wb') # 指定绝对路径 fw.write(r_pic.content) # 保存图片到本地指定目录 i += 1 update_file(each_url, t, htmlDir) # 将老的链接(有可能是相对链接)修改为本地的链接,这样本地打开整个html就能访问图片 fw.close() #下载html页面和图片 def save(search_response,file_name): htmlDir = os.path.join(os.path.dirname(os.path.abspath(__file__)), file_name) targetDir = os.path.join(os.path.dirname(os.path.abspath(__file__)),file_name+'\imgs1') # 图片保存的路径,eg,向前文件夹为'D:\Coding', 即图片保存在'D:\Coding\imgs1\' if not os.path.isdir(targetDir): # 不存在创建路径 os.makedirs(targetDir) domain = 'https://mp.weixin.qq.com/s' save_html(search_response, htmlDir,file_name) save_file_to_local(htmlDir, targetDir, search_response, domain) # 获得登录所需cookies with open("cookies.txt", "r") as file: cookie = file.read() cookies = json.loads(cookie) url = "https://mp.weixin.qq.com" response = requests.get(url, cookies=cookies) token = re.findall(r'token=(\d+)', str(response.url))[0] print(token) headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36", "Referer": "https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit_v2&action=edit&isNew=1&type=10&token="+token+"&lang=zh_CN", "Host": "mp.weixin.qq.com", } f = open("article_link.txt", encoding='utf-8') # 返回一个文件对象 line = f.readline() # 调用文件的 readline()方法 for line in open("article_link.txt", encoding='UTF-8'): new_line = line.strip() line_list = new_line.split("") file_name = line_list[0] dir_name = line_list[1] requestUrl = line_list[2] search_response = requests.get(requestUrl, cookies=cookies, headers=headers) save(search_response, file_name) print(file_name+"----------------下载完毕:"+dir_name+"----------------下载完毕:"+requestUrl) time.sleep(2) file.close()

11、下载后文章效果:

 

12、选择了google、百度、火狐、ie、Edge五种浏览器测试效果,其中google、百度、Edge浏览器正常打开带图片的页面,firefox浏览器只有文字,没有图片,ie打不开页面。综上,该爬取效果基本能满足需要。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有