"""通过搜狗搜索中的微信搜索入口爬取微信公众号文章(selenium)
"""
import re
import os
import json
import time
import requests
from pyquery import PyQuery
from urllib.parse import quote
from selenium import webdriverclass WeChatSpider:def __init__(self, keywords):"""构造函数"""self.keywords = keywords# 搜狐微信搜索链接入口self.so_gou_search_url = 'http://weixin.sogou.com/weixin?type=1&query=%s&ie=utf8&s_from=input&_sug_=n&_sug_type_=' % quote(self.keywords)# 爬虫伪装头部设置self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36'}# 设置操作超时时长self.timeout = 5# 爬虫模拟在一个request.session中完成self.s = requests.Session()def get_search_result_by_keywords(self):"""搜索入口地址,以公众为关键字搜索该公众号"""self.log('搜索地址为:%s' % self.so_gou_search_url)return self.s.get(self.so_gou_search_url, headers=self.headers, timeout=self.timeout).contentdef get_wx_url_by_sougou_search_html(self, sougou_search_html):"""根据返回sougou_search_html,从中获取公众号主页链接"""doc = PyQuery(sougou_search_html)return doc('div[class=txt-box]')('p[class=tit]')('a').attr('href')def get_selenium_js_html(self, url):"""执行js渲染内容,并返回渲染后的html内容"""browser = webdriver.Chrome()browser.get(url)time.sleep(3)html = browser.execute_script("return document.documentElement.outerHTML")return htmldef parse_wx_articles_by_html(self, selenium_html):"""从selenium_html中解析出微信公众号文章"""doc = PyQuery(selenium_html)print('开始查找内容msg')return doc('div[class="weui_media_box appmsg"]')def switch_arctiles_to_list(self, articles):"""把articles转换成数据字典"""# 定义存贮变量articles_list = []i = 1# 遍历找到的文章,解析里面的内容if articles:for article in articles.items():self.log(u'开始整合(%d/%d)' % (i, len(articles)))articles_list.append(self.parse_one_article(article))i += 1return articles_listdef parse_one_article(self, article):"""解析单篇文章"""# 获取标题title = article('h4[class="weui_media_title"]').text()self.log('标题是: %s' % title)# 获取标题对应的地址url = 'http://mp.weixin.qq.com' + article('h4[class="weui_media_title"]').attr('hrefs')self.log('地址为: %s' % url)# 获取概要内容summary = article('.weui_media_desc').text()self.log('文章简述: %s' % summary)# 获取文章发表时间date = article('.weui_media_extra_info').text()self.log('发表时间为: %s' % date)# 获取封面图片pic = self.parse_cover_pic(article)# 获取文章内容content = self.parse_content_by_url(url).html()# 存储文章到本地contentfiletitle = self.keywords + '/' + title + '_' + date + '.html'self.save_content_file(contentfiletitle, content)# 返回字典数据return {'title': title,'url': url,'summary': summary,'date': date,'pic': pic,'content': content}def parse_cover_pic(self, article):"""解析文章封面图片"""pic = article('.weui_media_hd').attr('style')p = re.compile(r'background-image:url\((.*?)\)')rs = p.findall(pic)self.log('封面图片是:%s ' % rs[0] if len(rs) > 0 else '')return rs[0] if len(rs) > 0 else ''def parse_content_by_url(self, url):"""获取文章详情内容"""page_html = self.get_selenium_js_html(url)return PyQuery(page_html)('#js_content')def save_content_file(self, title, content):"""页面内容写入文件"""with open(title, 'w', encoding="utf-8") as f:f.write(content)def save_file(self, content):"""数据写入文件"""with open(self.keywords + '/' + self.keywords + '.txt', 'w', encoding='utf-8') as f:f.write(content)def log(self, msg):"""自定义log函数,主要是加上时间"""print(u'%s: %s' % (time.strftime('%Y-%m-%d %H:%M:%S'), msg))# 验证函数def need_verify(self, selenium_html):"""有时候对方会封锁ip,这里做一下判断,检测html中是否包含id=verify_change的标签,有的话,代表被重定向了,提醒过一阵子重试 """return PyQuery(selenium_html)('#verify_change').text() != ''def create_dir(self):"""创建公众号命名的文件夹"""if not os.path.exists(self.keywords):os.makedirs(self.keywords)def run(self):"""爬虫入口函数 """# Step 0:创建公众号命名的文件夹self.create_dir()# Step 1:GET请求到搜狗微信引擎,以微信公众号英文名称作为查询关键字self.log(u'开始获取,微信公众号英文名为:%s' % self.keywords)self.log(u'开始调用sougou搜索引擎')sougou_search_html = self.get_search_result_by_keywords()# Step 2:从搜索结果页中解析出公众号主页链接self.log(u'获取sougou_search_html成功,开始抓取公众号对应的主页wx_url')wx_url = self.get_wx_url_by_sougou_search_html(sougou_search_html)self.log(u'获取wx_url成功,%s' % wx_url)# Step 3:Selenium获取渲染后的htmlself.log(u'开始调用selenium渲染html')selenium_html = self.get_selenium_js_html(wx_url)# Step 4: 检测目标网站是否进行了封锁if self.need_verify(selenium_html):self.log(u'爬虫被目标网站封锁,请稍后再试')else:# Step 5: 使用PyQuery,从Step 3获取的html中解析出公众号文章列表的数据self.log(u'调用selenium渲染html完成,开始解析公众号文章')articles = self.parse_wx_articles_by_html(selenium_html)self.log(u'抓取到微信文章%d篇' % len(articles))# Step 6: 把微信文章数据封装成字典的listself.log(u'开始整合微信文章数据为字典')articles_list = self.switch_arctiles_to_list(articles)# Step 7: 把Step 5的字典list转换为Jsonself.log(u'整合完成,开始转换为json')data_json = json.dumps(articles_list)# Step 8: 写文件self.log(u'转换为json完成,开始保存json数据到文件')self.save_file(data_json)self.log(u'保存完成,程序结束')if __name__ == '__main__':print("""********************************************    Welcome to Spider of 公众号       ** **      Created on 2018-11-15           ** **       @author: Feng mujin            ** ******************************************""")Subscription = input(u'输入要爬取的公众号: ')if not Subscription:Subscription = 'python6359'WeChatSpider(Subscription).run()
import re
import time
import json
import random
import requests
from selenium import webdriver# 微信公众号账号
user = "你的公众号账号"
# 公众号密码
password = "你的公众号密码"
# 设置要爬取的公众号列表
gzlist = ['要爬取的公众号名字']# 登录微信公众号,获取登录之后的cookies信息,并保存到本地文本中
def wechat_login():# 定义一个空的字典,存放cookies内容post = {}# 用webdriver启动谷歌浏览器print("启动浏览器,打开微信公众号登录界面")driver = webdriver.Chrome()# 打开微信公众号登录页面driver.get('https://mp.weixin.qq.com/')# 等待5秒钟time.sleep(5)print("正在输入微信公众号登录账号和密码......")# 清空账号框中的内容driver.find_element_by_xpath("./*//input[@id='account']").clear()# 自动填入登录用户名driver.find_element_by_xpath("./*//input[@id='account']").send_keys(user)# 清空密码框中的内容driver.find_element_by_xpath("./*//input[@id='pwd']").clear()# 自动填入登录密码driver.find_element_by_xpath("./*//input[@id='pwd']").send_keys(password)# 在自动输完密码之后需要手动点一下记住我print("请在登录界面点击:记住账号")time.sleep(10)# 自动点击登录按钮进行登录driver.find_element_by_xpath("./*//a[@id='loginBt']").click()# 拿手机扫二维码!print("请拿手机扫码二维码登录公众号")time.sleep(20)print("登录成功")# 重新载入公众号登录页,登录之后会显示公众号后台首页,从这个返回内容中获取cookies信息driver.get('https://mp.weixin.qq.com/')# 获取cookiescookie_items = driver.get_cookies()# 获取到的cookies是列表形式,将cookies转成json形式并存入本地名为cookie的文本中for cookie_item in cookie_items:post[cookie_item['name']] = cookie_item['value']cookie_str = json.dumps(post)with open('cookie.txt', 'w+', encoding='utf-8') as f:f.write(cookie_str)print("cookies信息已保存到本地")# 爬取微信公众号文章,并存在本地文本中
def get_content(query):# query为要爬取的公众号名称# 公众号主页url = 'https://mp.weixin.qq.com'# 设置headersheader = {"HOST": "mp.weixin.qq.com","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36"}# 读取上一步获取到的cookieswith open('cookie.txt', 'r', encoding='utf-8') as f:cookie = f.read()cookies = json.loads(cookie)# 登录之后的微信公众号首页url变化为:https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=1849751598,从这里获取token信息response = requests.get(url=url, cookies=cookies)token = re.findall(r'token=(\d+)', str(response.url))[0]# 搜索微信公众号的接口地址search_url = 'https://mp.weixin.qq.com/cgi-bin/searchbiz?'# 搜索微信公众号接口需要传入的参数,有三个变量:微信公众号token、随机数random、搜索的微信公众号名字query_id = {'action': 'search_biz','token': token,'lang': 'zh_CN','f': 'json','ajax': '1','random': random.random(),'query': query,'begin': '0','count': '5'}# 打开搜索微信公众号接口地址,需要传入相关参数信息如:cookies、params、headerssearch_response = requests.get(search_url, cookies=cookies, headers=header, params=query_id)# 取搜索结果中的第一个公众号lists = search_response.json().get('list')[0]# 获取这个公众号的fakeid,后面爬取公众号文章需要此字段fakeid = lists.get('fakeid')# 微信公众号文章接口地址appmsg_url = 'https://mp.weixin.qq.com/cgi-bin/appmsg?'# 搜索文章需要传入几个参数:登录的公众号token、要爬取文章的公众号fakeid、随机数randomquery_id_data = {'token': token,'lang': 'zh_CN','f': 'json','ajax': '1','random': random.random(),'action': 'list_ex','begin': '0',  # 不同页,此参数变化,变化规则为每页加5'count': '5','query': '','fakeid': fakeid,'type': '9'}# 打开搜索的微信公众号文章列表页appmsg_response = requests.get(appmsg_url, cookies=cookies, headers=header, params=query_id_data)# 获取文章总数max_num = appmsg_response.json().get('app_msg_cnt')# 每页至少有5条,获取文章总的页数,爬取时需要分页爬num = int(int(max_num) / 5)# 起始页begin参数,往后每页加5begin = 0while num + 1 > 0:query_id_data = {'token': token,'lang': 'zh_CN','f': 'json','ajax': '1','random': random.random(),'action': 'list_ex','begin': '{}'.format(str(begin)),'count': '5','query': '','fakeid': fakeid,'type': '9'}print('正在翻页:--------------', begin)# 获取每一页文章的标题和链接地址,并写入本地文本中query_fakeid_response = requests.get(appmsg_url, cookies=cookies, headers=header, params=query_id_data)fakeid_list = query_fakeid_response.json().get('app_msg_list')for item in fakeid_list:content_link = item.get('link')content_title = item.get('title')fileName = query + '.txt'with open(fileName, 'a', encoding='utf-8') as fh:fh.write(content_title + ":\n" + content_link + "\n")num -= 1begin = int(begin)begin += 5time.sleep(2)if __name__ == '__main__':try:# 登录微信公众号,获取登录之后的cookies信息,并保存到本地文本中wechat_login()# 登录之后,通过微信公众号后台提供的微信公众号文章接口爬取文章for query in gzlist:# 爬取微信公众号文章,并存在本地文本中print("开始爬取公众号:" + query)get_content(query)print("爬取完成")except Exception as e:print(str(e))

python 爬取微信公众号文章(selenium+webdriver)相关推荐

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

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

  2. Python爬取微信公众号文章、点赞数

    代码还是热乎的,只要你细心一步步的慢慢调试,绝壁没问题 前期准备 订阅号: Python: Fiddler: 微信账号: 流程 使用用微信公众号生成cookie 使用Fiddler抓取微信公众号数据, ...

  3. html如何获取请求头变量的值。_如何使用 Python 爬取微信公众号文章

    我比较喜欢看公众号,有时遇到一个感兴趣的公众号时,都会感觉相逢恨晚,想一口气看完所有历史文章.但是微信的阅读体验挺不好的,看历史文章得一页页的往后翻,下一次再看时还得重复操作,很是麻烦. 于是便想着能 ...

  4. python 微信公众号发文章_如何使用 Python 爬取微信公众号文章

    我比较喜欢看公众号,有时遇到一个感兴趣的公众号时,都会感觉相逢恨晚,想一口气看完所有历史文章.但是微信的阅读体验挺不好的,看历史文章得一页页的往后翻,下一次再看时还得重复操作,很是麻烦. 于是便想着能 ...

  5. 如何用python爬取公众号文章_如何使用 Python 爬取微信公众号文章

    我比较喜欢看公众号,有时遇到一个感兴趣的公众号时,都会感觉相逢恨晚,想一口气看完所有历史文章.但是微信的阅读体验挺不好的,看历史文章得一页页的往后翻,下一次再看时还得重复操作,很是麻烦. 于是便想着能 ...

  6. python爬虫爬取微信_如何使用 Python 爬取微信公众号文章

    我比较喜欢看公众号,有时遇到一个感兴趣的公众号时,都会感觉相逢恨晚,想一口气看完所有历史文章.但是微信的阅读体验挺不好的,看历史文章得一页页的往后翻,下一次再看时还得重复操作,很是麻烦. 于是便想着能 ...

  7. 如何使用 Python 爬取微信公众号文章

    我比较喜欢看公众号,有时遇到一个感兴趣的公众号时,都会感觉相逢恨晚,想一口气看完所有历史文章.但是微信的阅读体验挺不好的,看历史文章得一页页的往后翻,下一次再看时还得重复操作,很是麻烦. 于是便想着能 ...

  8. python爬取正确但不出文件_使用Python爬取微信公众号文章并保存为PDF文件(解决图片不显示的问题)...

    前言 第一次写博客,主要内容是爬取微信公众号的文章,将文章以PDF格式保存在本地. 爬取微信公众号文章(使用wechatsogou) 1.安装 pip install wechatsogou --up ...

  9. python爬取微信公众号文章

    爬取微信公众号文章 获取微信公众号的url 获取每一篇文章的url ​ 选择一个公众号进入,选择一个目录进入后点复制链接,然后去浏览器打开.按F12打开检查的模式,在Console中输入$x('标签路 ...

最新文章

  1. 为什么阿里巴巴要禁用 Executors 创建线程池?
  2. 深度学习人脸特征点自动定位综述
  3. python用Levenshtein计算文本相似度
  4. 鸟哥linux私房菜第6章笔记
  5. android jni new/delete 和 new[]/delete[]
  6. 文献记录(part44)--Skeletonisation algorithms with theoretical guarantees for unorganised point ...
  7. 教学平台服务器安装环境说明
  8. JavaScript基础知识(一)
  9. 国外大神一张图学会python-没有接触过编程Python难学吗?
  10. Java对MySql数据库进行备份与还原
  11. java实现阳历农历节以及节假日日期计算
  12. 微信公众号获取用户地理位置
  13. java模拟手机号码发短信_java实现发送手机短信
  14. VUE从一个页面传值到另一个页面
  15. 深度学习篇之数据集划分方法-附代码python详细注释
  16. Empire信息收集
  17. 奇点临近:人工智能让人类变成软件,并迅速统治宇宙
  18. 蓝海卓越 计费管理系统 download.php 任意文件读取漏洞
  19. 新浪微博新增评论带图功能
  20. Emlog最新付费模板带会员

热门文章

  1. 宽字符至多字符的相互转换方法
  2. python -- 负数平方根-虚数的使用
  3. 谣言!华为官方回应停止社会招聘
  4. 华为博士招聘上机考试题目_华为校园招聘上机考试题目
  5. 开关磁阻电机控制仿真(matlab 2016b版本仿真模型 自用)
  6. Excel 计算重复项中的唯一值的方法
  7. JS核心05:宿主对象dom和bom介绍
  8. cifar-100数据集转成图片格式
  9. html5对各浏览器的支持情况
  10. Nutanix CE版安装