目标

使用代理反爬抓取微信文章,获取文章标题、内容、公众号等信息,并存储到MongoDB数据库中。

流程框架

如果要抓取微信公众号文章可以使用搜狗的搜索引擎,它会显示最新的文章,但是有两个问题需要大家注意:

如果要抓取某一个主题(比如微信风景文章)的所有记录的话,需要先登录(也就是你的请求头headers中要有登陆之后服务器返回的cookies),未登录只可以查看10页,登录之后可以查看100页

搜狗微信站点的反爬措施比较严格,如果只是用本地IP(单IP)去抓取的话肯定是不行的,这个时候我们需要用到代理池技术(通过可用随机代理去绕过反爬机制)

关于代理池的实现以及使用可以参考这篇文章:使用Redis+Flask维护动态代理池

下图展示了具体的流程框架:

(1)抓取索引页内容

def parse_index(html):

doc = pq(html)

items = doc('.news-box .news-list li .txt-box h3 a').items()

for item in items:

yield item.attr('href')def parse_index(html):

doc = pq(html)

items = doc('.news-box .news-list li .txt-box h3 a').items()

for item in items:

yield item.attr('href')

在流程框架部分我们提到,在此将要使用搜狗搜索微信站点文章,首先让我们进入搜狗搜索界面https://weixin.sogou.com/,比如输入关键字风景,就会出现微信文章的列表。

从网页的url可以看出这是一个get请求,只保留主要参数,可以把url简化为

其中,“query”代表搜索的关键词,“type”代表搜索结果的类型,“type=1”表示搜索结果是微信公众号,“type=2”表示搜索结果是微信文章,“page”也就是当前页数。

分析完网页的url组成之后,我们先解决第一个问题:保存cookie,模拟登录。

打开浏览器控制台,选择NetWork->Headers选项卡,可以看到请求的headers信息。

解决完以上问题之后,让我们尝试写一下代码获取第1-100页的网页源码:

from urllib.parse import urlencode

import requests

base_url = 'https://weixin.sogou.com/weixin?'

# 构造请求头

headers = {

'Cookie': 'CXID=DF1F2AE56903B8B6289106D60E0C1339; SUID=F5959E3D8483920A000000005BCEB8CD; sw_uuid=3544458569; ssuid=8026096631; pex=C864C03270DED3DD8A06887A372DA219231FFAC25A9D64AE09E82AED12E416AC; SUV=00140F4F78C27EE25BF168CF5C981926; ad=p7R@vkllll2bio@ZlllllVsE@EclllllNBENLlllll9lllllpA7ll5@@@@@@@@@@; IPLOC=CN4110; ABTEST=2|1543456547|v1; weixinIndexVisited=1; sct=1; JSESSIONID=aaaXtNmDWRk5X5sEsy6Cw; PHPSESSID=lfgarg05due13kkgknnlbh3bq7; SUIR=EF72CF750D0876CFF631992E0D94BE34;',

'Host': 'weixin.sogou.com',

'Upgrade-Insecure-Requests': '1',

'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'

}

def get_html(url, count=1):

response = requests.get(url, allow_redirects=False, headers=headers)

# 判断网页返回的状态码是否正常

# 如果状态码是200说明可以正常访问

if response.status_code == 200:

return response.text

# 如果状态码是302,则说明IP已经被封

if response.status_code == 302:

return None

def get_index(keyword, page):

data = {

'query': keyword,

'type': 2,

'page': page

}

queries = urlencode(data)

url = base_url + queries

html = get_html(url)

return html

def main():

for page in range(1, 101):

html = get_index('风景', page)

print(html)

if __name__ == '__main__':

main()

运行以上代码,会发现刚开始运行正常,正确返回网页源码,之后便一直返回None,此时让我们打开浏览器观察一下:

可以看出,代码运行后不停返回None的原因是网页被重定向,需要输入验证码才能正常访问,这便是我们开篇说过的第二个问题,我们的访问被搜狗搜索的反爬虫措施拦截,如果想要继续正常访问,便需要利用代理池获取随机代理来绕过反爬机制。

(2)代理设置

在使用Redis+Flask维护动态代理池一文中,我们讲解了代理池的基本原理和简单实现,代码已托管到github上,现在让我们利用代理池来获取随机代理。

首先让我们定义get_proxy()方法,返回代理池获取的随机可用ip:

# flask监听的是5000端口

PROXY_POOL_URL = 'http://127.0.0.1:5000/get'

def get_proxy():

try:

response = requests.get(PROXY_POOL_URL)

if response.status_code == 200:

return response.text

return None

except ConnectionError:

return None

接下来修改get_html(url, count=1)方法,以随机ip的方式访问网页:

MAX_COUNT = 5

proxy = None

def get_html(url, count=1):

# 打印抓取的url

print('Crawling', url)

# 打印尝试抓取的次数

print('Trying Count', count)

global proxy

# 如果抓取的次数大于最大次数,则返回None

if count >= MAX_COUNT:

print('Tried Too Many Counts')

return None

try:

if proxy:

proxies = {

'http': 'http://' + proxy

}

# allow_redirects=False:禁止浏览器自动处理302跳转

response = requests.get(url, allow_redirects=False, headers=headers, proxies=proxies)

else:

response = requests.get(url, allow_redirects=False, headers=headers)

if response.status_code == 200:

return response.text

# 状态码是302,说明IP已经被封,调用get_proxy()获取新的ip

if response.status_code == 302:

# Need Proxy

print('302')

proxy = get_proxy()

if proxy:

print('Using Proxy', proxy)

return get_html(url)

else:

print('Get Proxy Failed')

return None

except ConnectionError as e:

# 如果连接超时,重新调用get_html(url, count)方法

print('Error Occurred', e.args)

proxy = get_proxy()

count += 1

return get_html(url, count)

再次运行代码,会发现不停重复打印None的情况基本消失。大家注意,这里是基本消失,原因是我们的代理池使用的是免费代理网站获取的代理,同一时刻可能会有许多人访问,这样就很容易造成ip地址被封的情况。如果你想要获取更好的效果,不妨使用一下收费代理。

至此,我们解决了开篇提到的两个问题,接下来,就可以抓取网页,分析内容。

(3)分析详情页内容

首先我们需要获取到第1-100页中每一篇文章的url:

def parse_index(html):

doc = pq(html)

items = doc('.news-box .news-list li .txt-box h3 a').items()

for item in items:

yield item.attr('href')

def main():

for page in range(1, 101):

html = get_index(KEYWORD, page)

if html:

article_urls = parse_index(html)

print(article_urls)

获取到每一篇文章的url之后,就需要解析每一篇文章的内容。解析方法与上面相同,在此不再赘述。具体代码如下:

def parse_detail(html):

try:

doc = pq(html)

title = doc('.rich_media_title').text()

content = doc('.rich_media_content ').text()

date = doc('#publish_time').text()

nickname = doc('.rich_media_meta_list .rich_media_meta_nickname').text()

wechat = doc('#activity-name').text()

return {

'title': title,

'content': content,

'date': date,

'nickname': nickname,

'wechat': wechat

}

except XMLSyntaxError:

return None

需要注意的一点就是需要捕获XMLSyntaxError异常。

(4)将数据保存到数据库

最后让我们新建一个config.py文件,文件中包含了MongoDB的URL,数据库名称,表名称等常量:

MONGO_URL = 'localhost'

MONGO_DB = 'weixin'

在spider.py中配置存储到MongoDB相关方法:

from config import *

import pymongo

client = pymongo.MongoClient(MONGO_URL)

db = client[MONGO_DB]

def save_to_mongo(data):

if db['articles'].update({'title': data['title']}, {'$set': data}, True):

print('Saved to Mongo', data['title'])

else:

print('Saved to Mongo Failed', data['title'])

运行代码,接下来在MongoDB中进行查看:

使用代理爬去微信公众号_使用代理处理反爬抓取微信文章相关推荐

  1. python爬虫能爬取微信密码吗_如何利用Python网络爬虫抓取微信好友数量以及微信好友的男女比例...

    今天我们继续focus on微信,不过这次给大家带来的是利用Python网络爬虫抓取微信好友总数量和微信好友男女性别的分布情况.代码实现蛮简单的,具体的教程如下. 相信大家都知道,直接通过网页抓取微信 ...

  2. python自动发送微信公众号_使用python一步一步搭建微信公众平台(四)----将小黄鸡引入微信自动回复...

    通过前三篇的教程,相信大家基本上了解了微信开发的基本流程,先判断用户传入数据的类型MsgType,然后再获取用户输入的内容content,再对content进行处理,再返回给用户 现在我们来加点料,在 ...

  3. 微信公众号_订阅号+服务号开发工具包-翟东平-专题视频课程

    微信公众号_订阅号+服务号开发工具包-15114人已学习 课程介绍         "微信公众平台深度开发Java版 v2.0"系列课程共有6季,使用JAVA语言,系统讲解微信公众 ...

  4. app怎么调起微信公众号_小程序_微信群_企业微信Html

    如何从APP跳转公众号小程序企微有多种方式,如下: 方法一:app怎么调起微信公众号 1.进入天天外链 2.复制你的公众号文章链接 3.将链接填入天天外链 4.复制生成的链接放入您开发的APP中即可. ...

  5. Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发

    接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 3.依据接口文档实现业务逻辑 资料准备: 1.一个可以访问的外网,即80的访问端口,因为微信公众号接 ...

  6. 使用代理爬去微信公众号_使用微信公众号开发模拟面试功能

    猫 最近在整理我在大厂面试以及平时工作中遇到的问题,记录在 shfshanyue/Daily-Question[1] 中,但觉得对于时时回顾,常常复习仍然做的不够. 于是在微信公众号中开发了随机生成模 ...

  7. 使用代理爬去微信公众号_公众号粉丝从0到1000的引流思路企业如何做好微信公众号运营?公众号运营技巧,你都知道吗?微信公众号怎么去推广运营?...

    一直以来,公众号打开率持续走低几乎成了一个行业共识.但事实上,过去一年微信公众平台的整体流量是上升的. "上升幅度在内部看来还不小."微信公众平台相关负责人表示. 但为什么平摊至每 ...

  8. 使用代理爬去微信公众号_爬虫之使用代理爬取微信公众号文章(下)

    一 修改代理池 1 将代理池中TEST_URL的地址修改为:TEST_URL = 'https://weixin.sogou.com/weixin?type=2&query=NBA' 2 运行 ...

  9. 使用代理爬去微信公众号_微信公众号怎么去推广运营?企业微信公众号要如何运营?微信公众号运营技巧,你get了吗?微信怎么去推广运营?...

    公众号排名的网站,这类状况下是不可能会被被严厉打击悬架的,不得不下拉列表的连接,网站,这种关键字的连接.网址便是对网址有益于排名的网站 网址的网址的内容,假如网址网址的内容.外部链接的网址,有利于提升 ...

  10. 微信公众号JS-SDK多图上传爬坑指南

    一.wx.chooseImage爬坑 出现的问题: 安卓将chooseImage 方法返回的 localId 放在img标签的src属性下能够显示图片 IOS将chooseImage 方法返回的 lo ...

最新文章

  1. HALCON测量工具
  2. window环境使用C++实现WebSocket
  3. android自定义抽奖,Android自定义view制作抽奖转盘
  4. 需求用例分析之二:级别设置
  5. 第一章 关于python
  6. Python中生成器generator和迭代器Iterator的使用方法
  7. C#调用WebKit内核
  8. 威海二职工业机器人专业_工业机器人专业就业前景-山东省好的中专学校
  9. pytorch利用rnn通过sin预测cos 利用lstm预测手写数字
  10. 杨元庆:出身中国是联想吸引国际用户的障碍
  11. 【开源】对基于图像背景的字体生成、人体姿势预测、关键点检测、超分辨率等探讨...
  12. 转载:做了5年运维,靠着这份监控知识体系,我从3K变成了40K
  13. Cobbler安装指南
  14. JavaScript 实现:输出斐波那契数列
  15. 区块链应用大数据的优势有哪些
  16. 陈桥五笔用户编号怎么获取_从五笔转向双拼输入法
  17. LabelImg操作手册
  18. sdr 软件_购买软件定义无线电(SDR)还是传统无线电台?|追求欲望无止境
  19. Android天气预报详解
  20. AB测试-最佳方案测试

热门文章

  1. linux 该文件的owner,Linux修改文件/目录的owner/group方法(转载)
  2. OEM、ODM、OBM分别是什么?
  3. 什么是变量?变量的命名规则?变量的分类?(问号三连)
  4. 夜神模拟器如何设置自动代理
  5. 魔兽争霸lostTemple地图
  6. 气球java游戏_团队游戏 气球
  7. 技术经理、架构师、技术总监、VP、CTO,这些岗位都是如何挣出来
  8. 查看显卡型号命令_ubuntu查看显卡型号方法有哪些
  9. [深度学习概念]·非极大值抑制解析
  10. java is alphabetic_java中的java.lang.Character类 – 方法| 2 - Break易站