使用代理爬取微信文章

思路:

  使用搜狗搜索爬取微信文章时由于官方有反爬虫措施,不更换代理容易被封,所以使用更换代理的方法爬取微信文章,代理池使用的是GitHub上的开源项目,地址如下:https://github.com/jhao104/proxy_pool,代理池配置参考开源项目的配置。

步骤:

1)分析网页结构,拿到网页请求参数

2)构造请求参数,获取索引页内容:

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

3)主要讲下代理IP的实现方法,先设置本地IP为默认代理,定义获取代理池IP地址的函数,当爬取出现403错误的时候更改代理,在获取网页源代码的时候传入代理IP地址,若获取网页源代码失败再次调用 get_html() 方法,再次进行获取尝试。

#初始化代理为本地IP
proxy = None

#定义获取代理函数
def get_proxy():
    try:
        response = requests.get('PROXY_POOL_URL')
        if response.status_code == 200:
            return response.text
        return None
    except ConnectionError:
        return None

#添加代理获取网页内容
def get_html(url, count=1):
    print('Crawling', url)
    print('Trying Count', count)
    global proxy
    if count >= MAX_COUNT:
        print('Tried Too Many Counts')
        return None
    try:
        if proxy:
            proxies = {
                'http': 'http://' + proxy
            }
            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
        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:
        print('Error Occurred', e.args)
        proxy = get_proxy()
        count += 1
        return get_html(url, count)

4)使用 pyquery 获取详情页详细微信文章信息(如:微信文章标题、内容、日期、公众号名称等):

def parse_detail(html):
    try:
        doc = pq(html)
        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()
        return {
            'title': title,
            'content': content,
            'date': date,
            'nickname': nickname,
            'wechat': wechat
        }
    except XMLSyntaxError:
        return None

5)存储到MongoDB,去重操作:

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'])

操作过程:

1)开启代理池:

2)运行 spider.py 文件:

3) 查看保存在MongoDB的内容:

完整代码在GitHub上:https://github.com/weixuqin/PythonProjects/tree/master/WeixinArticles

PS:当我使用配置好的默认参数文件 config.py ,并导入当前目录下的 spider.py , 发现 pycharm 提示我错误,实际上并没有出错

原因是 pycharm 不会将当前文件目录自动加入自己的 sourse_path ,所以需要我们手动导入:右键make_directory as-->sources path将当前工作的文件夹加入source_path。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏步履前行

Spring Retry

  在我们的业务场景中,经常要调用其他的API来获取信息,比如我们的业务场景需要依赖个人信息来处理,这个时候调用个人信息服务的API,但是由于可能同一时段多方在...

2343
来自专栏抠抠空间

Linux用户管理

2740
来自专栏Java帮帮-微信公众号-技术文章全总结

Web-第三十一天 WebService学习【悟空教程】

简单的网络应用使用单一语言写成,它的唯一外部程序就是它所依赖的数据库。大家想想是不是这样呢?

1754
来自专栏SDNLAB

POF技术分享(二):POF交换机源码结构

一:函数调用关系图 POF交换机先会进行基本配置的初始化、交换机资源初始化等,然后开启交换机与控制器通信进程,建立连接进行通信,最后开启基于流表的数据包匹配与处...

3617
来自专栏草根专栏

用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识 + 项目准备

REST 是 Representational State Transfer 的缩写. 它是一种架构的风格, 这种风格基于一套预定义的规则, 这些规则描述了网络...

1K6
来自专栏张戈的专栏

Linux运维工程师:30道面试题整理

前段时间,我在准备面试的时搜到的一套 Linux 运维工程师面试题,感觉比较全面,一直保存在草稿,刚在整理后台时翻了出来,干脆就发出来好了,以备不时之需。 1....

1.5K5
来自专栏拂晓风起

Spring 获取web根目录 (Spring线程获取web目录/路径/根目录,普通类获取web目录)

1023
来自专栏张善友的专栏

利用Windows性能计数器(PerformanceCounter)监控

一、概述 性能监视,是Windows NT提供的一种系统功能。Windows NT一直以来总是集成了性能监视工具,它提供有关操作系统当前运行状况的信息,针对各种...

2919
来自专栏解Bug之路

MySql-Binlog协议详解-报文篇

#MySql-Binlog协议详解-报文篇 紧接上篇流程篇,本篇主要将binlog的event报文。 ##Event报文分层 event报文主要分三层。 (1...

1313
来自专栏软件开发 -- 分享 互助 成长

linux下进程相关操作

一、定义和理解 狭义定义:进程是正在运行的程序的实例。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。 进程的概念主要有两点: 第一...

2135

扫码关注云+社区