GitHub:

https://github.com/utopianist/SougouWeixin


前言

上节我们爬完了所有索引页,这节我们开始爬取公众号文章。

要知道,我们之前爬的是 weixin.sogou.com ,而现在爬取的是 mp.weixin.qq.com ,这是两个完全不同的网站。

关于 mp.weixin.qq.com 的反爬,并不是很严厉,我们只需需要构造新的请求头。

硬说有的话,那就是:首先,我们爬取的 requests 队列里的 URL 链接有时效性,争取在 12 小时内使用。

其次,注意到上面的链接,都是 http 开头,而正式请求时的链接都是 https 开头。这时我们要打开我们 GET 请求的重定向开关。

清洗代理

对,又要清洗代理,不要觉得这步很繁琐,这是提高我们爬虫体验极其关键的一步。

打开我们的代理池文件夹 proxypool ,找到里面的 setting.py ,

TEST_URL 改成 “https://mp.weixin.qq.com/”,

REDIS_KEY改成 “weixinproxies”。

爬取微信公众号文章

在运行代理池后,我们积累足够多能爬取 mp.weixin.qq.com的健康代理。

在上节提到的 db.py 文件中,加入 weixin_proxy_random()weixin_proxy_decrease() 两个函数。

目的是,便于提取 ”weixinproxies“里的代理。

db.py
import redis
from random import choice
from weixin.error import PoolEmptyError# Redis数据库地址
REDIS_HOST = 'localhost'# Redis端口
REDIS_PORT = 6379# Redis密码,如无填None
REDIS_PASSWORD = NoneWEIXIN_PROXY_REDIS_KEY = 'weixinproxies'#最大评分
MAX_SCORE = 100
MIN_SCORE = 0class RedisClient(object):def __init__(self, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD):"""初始化:param host: Redis 地址:param port: Redis 端口:param password: Redis密码"""self.db = redis.StrictRedis(host=host, port=port, password=password, decode_responses=True)def weixin_proxy_random(self):"""随机获取有效代理,首先尝试获取最高分数代理,如果不存在,按照排名获取,否则异常:return: 随机代理"""result = self.db.zrangebyscore(WEIXIN_PROXY_REDIS_KEY, MAX_SCORE, MAX_SCORE)if len(result):return choice(result)else:result = self.db.zrevrange(WEIXIN_PROXY_REDIS_KEY, 0, 100)if len(result):return choice(result)else:raise PoolEmptyErrordef weixin_proxy_decrease(self, proxy):"""代理值减一分,小于最小值则删除:param proxy: 代理:return: 修改后的代理分数"""score = self.db.zscore(WEIXIN_PROXY_REDIS_KEY, proxy)if score and score > MIN_SCORE:print('代理', proxy, '当前分数', score, '减1')return self.db.zincrby(WEIXIN_PROXY_REDIS_KEY, proxy, -1)else:print('代理', proxy, '当前分数', score, '移除')return self.db.zrem(WEIXIN_PROXY_REDIS_KEY, proxy)

接下来我们创建一个名为 articles.py 的文件。

articles.py
import requests
from weixin.db import RedisClient
from weixin.mysql import MySQL
from pyquery import PyQuery as pq#合法状态码
VALID_STATUSE = [200]class Articles():headers = {'Host': 'mp.weixin.qq.com','User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0','Accept': '*/*','Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2','Accept-Encoding': 'gzip, deflate, br','Referer': 'https://mp.weixin.qq.com/s?src=11&timestamp=1543224952&ver=1268&signature=n0EW*NEa73Cd39RmRKfaYPU5NUDuN5X6eypDap*--nQ913dIIe3i8EcRnyd7PptsjOAKzDVuI*ikSsioBg0*zMGPbB27CUrORDvEMav2hvZHp2tFF3V4cNyl09Cr73Rl&new=1','Cookie': 'rewardsn=; wxtokenkey=777','Connection': 'keep-alive',}redis = RedisClient()mysql = MySQL()proxies = Nonedef test_proxy(self):"""二次清洗代理:return:"""global proxiesurl = 'https://mp.weixin.qq.com'proxy = self.redis.weixin_proxy_random()proxies = {'http': 'http://' + proxy,'https': 'https://' + proxy}try:r = requests.get(url, headers=self.headers, allow_redirects=False, proxies=proxies, timeout=30)if r.status_code == 200:passelse:self.redis.weixin_proxy_decrease(proxy)self.test_proxy()except:self.redis.weixin_proxy_decrease(proxy)self.test_proxy()def start(self):global proxieswhile not self.redis.request_empty():url = self.redis.request_pop()try:response = requests.get(url, headers=self.headers, proxies=proxies, allow_redirects=True, timeout=20)print('正在爬取:', url)print(response.status_code)if response and response.status_code in VALID_STATUSE:print('status_code:200')self.parse_detail(response)else:self.test_proxy()self.redis.request_add(url)except:self.test_proxy()self.redis.request_add(url)def parse_detail(self, response):"""解析详情页:param response: 响应:return: 微信公众号文章"""doc = pq(response.text)data = {'title': doc('.rich_media_title').text(),'content': doc('.rich_media_content').text(),'date': doc('#post-date').text(),'nickname': doc('#js_profile_qrcode > div > strong').text(),'wechat': doc('#js_profile_qrcode > div > p:nth-child(3) > span').text()}if not len(data) == 0:self.mysql.insert('articles', data)

函数 parse_detail() 在接收 response 后,用 PyQuery 解析,再把数据保存到 Mysql。

在编写 mysql.py 之前,我们要先配置好自己的 Mysql,创建一个名为 “weixin”的数据库,还有一系列参数。

然后我们还有在数据库 “weixin”中创建一个名为 “articles”的数据表,SQL 语句:

CREATE TABLE 'articles' ('title' varchar(255) NOT NULL,'content' text NOT NULL,'date' varchar(255) NOT NULL,'wechat' varchar(255) NOT NULL,'nickname' varchar(255) NOT NULL,
)DEFAULT CHARSET=utf8;
mysql.py
import pymysqlMYSQL_HOST = 'localhost'MYSQL_PORT = 3306MYSQL_USER = 'root'MYSQL_PASSWORD = '123456'MYSQL_DATABASE = 'weixin'class MySQL():def __init__(self, host=MYSQL_HOST, username=MYSQL_USER, password=MYSQL_PASSWORD, port=MYSQL_PORT,database=MYSQL_DATABASE):"""MySQL初始化:param host::param username::param password::param port::param database:"""try:self.db = pymysql.connect(host, username, password, database, charset='utf8', port=port)self.cursor = self.db.cursor()except pymysql.MySQLError as e:print(e.args)def insert(self, table, data):"""插入数据:param table::param data::return:"""keys = ', '.join(data.keys())values = ', '.join(['%s'] * len(data))sql_query = 'insert into %s (%s) values (%s)' % (table, keys, values)try:self.cursor.execute(sql_query, tuple(data.values()))self.db.commit()print('存入mysql')except pymysql.MySQLError as e:print(e.args)self.db.rollback()

至此,爬取搜狗微信文章就算完成。我们就有超多文章可以看了,

然而,并没有太大卵用。

总结

代码性能

在爬取速率上,我并没有采取一些加速的方法,比如异步协程等等。

因为我害怕触发更加强大的反爬。

毕竟爬和反爬就是“道高一尺,魔高一丈”的事情,既然我们可以完成我们的爬取任务,为何不绅士一点?

使用场景

这套爬取方法,只适合小型爬取,给新手练练手。

全站爬取,还要考虑其他接口。

而且,搜狗微信提供的接口,缺少一些更加振奋人心的参数。比如:文章阅读量,文章赞赏量等等。

最后

欢迎关注我的公众号 爬虫小栈。

搜狗微信文章爬取(下)相关推荐

  1. 搜狗微信文章爬取(中)

    GitHub: https://github.com/utopianist/SougouWeixin 前言 上节,我们已经成功构造了包含参数 SNUID 的 Cookie 池,这节我们将正式爬取 we ...

  2. 爬取搜狗微信文章笔记1

    爬取搜狗微信文章笔记1 错误1 ```pythonprint('https://weixin.sogou.com'+index) TypeError: can only concatenate str ...

  3. 微信公众号文章爬取方法整理

    微信公众号文章爬取方法整理 1.用python爬取 http://blog.csdn.net/d1240673769/article/details/75907152 实现方法:通过微信提供的公众号文 ...

  4. python3实现微信公众号文章爬取

    基于搜狗微信的文章爬取 前言:文章仅用于学习交流,不足之处欢迎小伙伴指正! 一.功能介绍: 已实现功能: 1.爬取搜狗微信上的分类一栏的所有事件及其他的所有标题事件和加载更多,返回文章链接与标题,并存 ...

  5. python微信爬取教程_[python]微信公众号文章爬取

    [python]微信公众号文章爬取 需求 爬取一些微信公众号的文章 数据来源 1.搜狗微信搜索,可以搜索微信公众号文章,但只能显示该公众号最近十篇的文章 2.通过个人微信公众号中的素材管理,查看其他微 ...

  6. Python 微信公众号的文章爬取

    Python 微信公众号文章爬取 一.思路 二.接口分析 三.实现 第一步: 第二步: 1.请求获取对应公众号接口,取到我们需要的fakeid 2.请求获取微信公众号文章接口,取到我们需要的文章数据 ...

  7. 【java】微信文章抓取

    1.搜狗微信url解析 以搜索湖北师范大学为例: 请求的url为: http://weixin.sogou.com/weixin?query=%E6%B9%96%E5%8C%97%E5%B8%88%E ...

  8. 搜狗·疫情数据爬取(Python)

    上周已经分享过搜狗·疫情数据爬取(R语言),这次分享一下搜狗·疫情数据爬取(Python) 不说废话,直接上代码.有什么问题,可以在留言区讨论. from urllib import request ...

  9. 微信文章抓取:微信临时链接转永久链接方法,一招摆脱链接过期烦恼

    上一篇文章<微信文章抓取:微信公众号文章抓取常识之临时链接.永久链接>中介绍了微信临时链接和微信永久链接的情况.那么大家一定会有一个问题:如何让临时链接不再过期?或者说如何把临时链接转换为 ...

  10. Python 爬虫 :搜狗百科,爬取多个人名的属性表信息 pycharm selenium

    任务名称: 在搜狗百科上爬取一些人名的属性表信息 任务来源: 初学爬虫,牛刀小试 开发工具: PyCharm 开发团队: 213 开发人员: 小鞋带.小泽.阿烨 开发时间: 2019-12-15 20 ...

最新文章

  1. MySQL新建数据库+用Navicat查看MySQL的方法
  2. R语言eval函数评估表达式或者字符串实战
  3. hdu 5062(dp)
  4. 项目war包部署到第三方Tomcat,访问路径必须加上项目名称的坑
  5. Android之Http网络编程(四)
  6. MySQL后初次密码_mysql第一次安装成功后初始化密码操作步骤
  7. webserver之使用数组实现阻塞队列
  8. 清除B/S开发时页面缓存
  9. oracle数据库xsb创建,在Linux下安装oracle数据库
  10. FFmpeg之视频转码
  11. python一元二次方程组
  12. 投资百万运营网站 为何只坚持了一年?
  13. Linux关闭防火墙命令总结
  14. java微信网页支付_java实现微信H5支付
  15. 2013年第4季度橱柜品牌网络知名度排名
  16. 防洪决策指挥系统(Axure高保真原型)
  17. 未能加载文件或程序集“Newtonsoft.Json,Version = 13.0.0.0,Culture = neutral,PublicKeyToken = 30ad4fe6b2a6aeed“..
  18. android电视直播卡顿,电视盒子看直播卡顿原因分析以及教你解决方法!
  19. brainproduct recorder 远程采集脑电波实时数据
  20. [C语言小游戏]----多子棋小游戏

热门文章

  1. 线程生命周期(状态)
  2. 【大厂面试必备系列】滑动窗口协议
  3. lora终端连接云服务器_云服务器如何连接LoRa网关
  4. URAL 2037 Richness of binary words
  5. 580刷590bios_老司机带你开车,迪兰570怒刷580BIOS超频至1430M
  6. 如何优化MySQL千万级大表,我写了6000字的解读
  7. C++课程设计--人民币大小写转换器(MFC)
  8. 随机抖音接口php,【php】下载抖音无水印视频接口
  9. 高中数学建模优秀论文_数学建模优秀论文范文
  10. 系列学习 Lambda 表达式之第 2 篇 —— JDK1.8 的 Stream 流基本使用