专栏首页Python爬虫与算法进阶Python分布式微博爬虫(源码分享)

Python分布式微博爬虫(源码分享)

项目地址:https://github.com/ResolveWang/weibospider 作者:resolvewang

关于本项目

  • 实现内容包括用户信息、用户主页所有微博、微博搜索、微博评论和微博转发关系抓取等
  • 本项目基于本人实际的工作,并对此做了大量的修改和改进。希望能帮到对微博数据采集有需求的同学,对爬虫进阶 感兴趣的同学也可以看看。该项目从模拟登陆到各个页面的请求、从简单页面到复杂页面解析处理和相关的异常处理、 从单机到分布式迁移都做了大量的工作和反复测试,花了我绝大部分业余的时间

你可以用它来干嘛

  • 微博舆情分析
  • 论文撰写的一些数据,本项目会将抓到的所有数据不定时公布(资源和精力有限,暂时只有19.1w条微博用户数据)
  • 自然语言处理的语料,比如热门微博的所有评论
  • 爬虫进阶学习,对于需要学习Python进阶和爬虫的同学来说,都可以读读源码

为何选择本项目

  • 功能全面:包括了用户信息抓取、指定关键字搜索结果增量抓取、指定用户主页所有微博抓取、评论抓取和转发关系抓取等
  • 数据全面:PC端展现的数据量比移动端更加丰富。并且相比于其它同类项目对微博的简单分析,本项目做了大量细致的工作, 比如不同 domain 不同用户的解析策略、不同 domain 不同用户的主页分析策略等
  • 稳定!项目可以长期稳定运行。
  • 为了保证程序能长期稳定运行,数据所有的网络请求都是通过抓包手动分析的,未用任何自动化工具, 包括模拟登陆!从另一个方面来说,抓取速度也是比较有保证的(主要还是看账号数量)
  • 通过合理的阈值设定,账号可以保证安全
  • 即使账号不可用或者登陆失败,项目都对其做了处理(智能冻结账号,出错重试等),以保证每次请求都是有效的,并及时把错误反馈给用户
  • 通过大量的异常检测和处理,几乎捕获了所有的解析和抓取异常。编写了大量的解析代码来获取足够全面的信息
  • 复用性和二次开发性很好。项目很多地方都有详细的代码注释,方便阅读。即使本项目不能完全满足你 对微博数据采集和分析的需求,你也可以自己在该项目的基础上做二次开发,项目已经在微博抓取和各个 模版解析上做了大量工作。
  • 由于本项目与本人实际工作有关联(代码并不是工作中使用的代码),所以可以放心它会长期更新。目前已经迭代一年有余了。
  • 丰富文档支持:请点击wiki查看所有文档。如果文档仍然不能解决你的问题,推荐提issue,我们开发者看到后都会积极回答,也可以 通过加QQ群进行交流。注意在群里没事就潜水,有问题就问,开发者会积极回答。
# coding:utf-8
import time
from db import wb_data
from tasks.workers import app
from page_parse import comment
from config import conf
from page_get.basic import get_page
from db.weibo_comment import save_comments

# 起始请求地址
base_url = 'http://weibo.com/aj/v6/comment/big?ajwvr=6&id={}&page={}&__rnd={}'


@app.task(ignore_result=True)
def crawl_comment_by_page(mid, page_num):
    cur_time = int(time.time() * 1000)
    cur_url = base_url.format(mid, page_num, cur_time)
    html = get_page(cur_url, user_verify=False)
    comment_datas = comment.get_comment_list(html, mid)
    save_comments(comment_datas)
    if page_num == 1:
        wb_data.set_weibo_comment_crawled(mid)
    return html


@app.task(ignore_result=True)
def crawl_comment_page(mid):
    limit = conf.get_max_comment_page() + 1
    # 这里为了马上拿到返回结果,采用本地调用的方式
    first_page = crawl_comment_by_page(mid, 1)
    total_page = comment.get_total_page(first_page)

    if total_page < limit:
        limit = total_page + 1

    for page_num in range(2, limit):
        app.send_task('tasks.comment.crawl_comment_by_page', args=(mid, page_num), queue='comment_page_crawler',
                      routing_key='comment_page_info')


@app.task(ignore_result=True)
def excute_comment_task():
    # 只解析了根评论,而未对根评论下的评论进行抓取,如果有需要的同学,可以适当做修改
    weibo_datas = wb_data.get_weibo_comment_not_crawled()
    for weibo_data in weibo_datas:
        app.send_task('tasks.comment.crawl_comment_page', args=(weibo_data.weibo_id,), queue='comment_crawler',
                      routing_key='comment_info')

项目结构

  • 功能模块
  • 微博模拟登陆任务 login.py
  • 微博用户抓取任务 user.py
  • 微博特定话题搜索任务 search.py
  • 微博用户主页信息抓取任务 home.py
  • 微博评论抓取任务 comment.py
  • 微博转发抓取任务 repost.py

配置和使用

  • 环境配置:小白和新手请直接查看这里
  • 考虑到Python3是趋势和一些将该项目用于学习的用户,项目运行环境为Python3.x
  • 项目存储后端使用Mysql,所以需要在存储服务器上安装Mysql,注意设置字符集编码为utf-8
  • 由于项目是使用celery做分布式任务调度,所以 需要使用broker和各个分布式节点通信,项目使用的是Redis,所以需要先安装Redis。 注意修改Redis的配置文件让它能监听除本机外的别的节点的请求,建议给Redis设置密码,如 果没设置密码,需要关闭保护模式(不推荐,这个有安全风险)才能和各个节点通信。如果害怕遇到Redis单点 故障,可以使用Redis主从配置。

入口文件:如果有同学有修改源码的需求,那么建议从入口文件开始阅读

  • login.py和login_first.py:PC端微博登陆程序
  • user.py和user_first.py:微博用户抓取程序
  • search.py和search_first.py:微博话题搜索程序
  • home.py和home_first.py:微博用户主页所有微博抓取程序
  • comment.py和comment_first.py:微博评论抓取
  • repost.py和repost_first.py:转发信息抓取
# coding:utf-8
import time
from logger.log import crawler
from tasks.workers import app
from page_parse.user import public
from page_get.basic import get_page
from db.wb_data import insert_weibo_datas
from db.seed_ids import get_home_ids
from config.conf import get_max_home_page
from page_parse.home import get_wbdata_fromweb, get_home_wbdata_byajax, get_total_page


# 只抓取原创微博
home_url = 'http://weibo.com/u/{}?is_ori=1&is_tag=0&profile_ftype=1&page={}'
ajax_url = 'http://weibo.com/p/aj/v6/mblog/mbloglist?ajwvr=6&domain={}&pagebar={}&is_ori=1&id={}{}&page={}' \
           '&pre_page={}&__rnd={}'


@app.task(ignore_result=True)
def crawl_ajax_page(url):
    """
    返回值主要供第一次本地调用使用(获取总页数),网络调用忽略返回值
    :param url: 
    :return: 
    """
    ajax_html = get_page(url, user_verify=False)
    ajax_wbdatas = get_home_wbdata_byajax(ajax_html)
    if not ajax_wbdatas:
        return ''

    insert_weibo_datas(ajax_wbdatas)
    return ajax_html


@app.task(ignore_result=True)
def crawl_weibo_datas(uid):
    limit = get_max_home_page()
    cur_page = 1
    while cur_page <= limit:
        url = home_url.format(uid, cur_page)
        html = get_page(url)
        weibo_datas = get_wbdata_fromweb(html)

        if not weibo_datas:
            crawler.warning('用户id为{}的用户主页微博数据未采集成功,请检查原因'.format(uid))
            return

        insert_weibo_datas(weibo_datas)

        domain = public.get_userdomain(html)
        cur_time = int(time.time()*1000)
        ajax_url_0 = ajax_url.format(domain, 0, domain, uid, cur_page, cur_page, cur_time)
        ajax_url_1 = ajax_url.format(domain, 1, domain, uid, cur_page, cur_page, cur_time+100)

        if cur_page == 1:
            total_page = get_total_page(crawl_ajax_page(ajax_url_1))

        if total_page < limit:
            limit = total_page

        cur_page += 1
        app.send_task('tasks.home.crawl_ajax_page', args=(ajax_url_0,), queue='ajax_home_crawler',
                      routing_key='ajax_home_info')

        app.send_task('tasks.home.crawl_ajax_page', args=(ajax_url_1,), queue='ajax_home_crawler',
                      routing_key='ajax_home_info')


@app.task
def excute_home_task():
    # 这里的策略由自己指定,可以基于已有用户做主页抓取,也可以指定一些用户,我这里直接选的种子数据库中的uid
    id_objs = get_home_ids()
    for id_obj in id_objs:
        app.send_task('tasks.home.crawl_weibo_datas', args=(id_obj.uid,), queue='home_crawler',
                      routing_key='home_info')

基本用法:请按照启动worker=>运行login_first.py=> 启动定时任务或者别的任务这个顺序进行

使用任务路由的最大好处是你可以为不同的节点分配不同的任务,这样让整个系统的数据采集效率更高。比如用户抓取,一个http请求只能得到一个用户信息,而对于用户关注和粉丝抓取,一个http请求可以得到几十个关注或者粉丝用户的uid,所以可以部署一个用户关注或者粉丝抓取节点,部署10个或者更多的用户信息抓取节点,让任务能比较均衡地执行。

找一个明星,试试爬取全部内容吧!

本文分享自微信公众号 - Python爬虫与算法进阶(zhangslob),作者:resolvewang

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-07-12

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 使用pyppeteer淘宝登录

    现在淘宝的商品搜索页必须要登录才能见,所以必须要cookies才能进行下一步操作。本期介绍如何使用pyppeteer登录淘宝,获取Cookies。

    小歪
  • JS逆向常见混淆总结

    小歪
  • 反反爬虫系列(一)

    笔者决定写一个系列反反爬虫,目的是站在生产角度如何绕过各类网站的反爬虫,提供反反爬虫思路。

    小歪
  • 如何在django中实现分页功能

    砸漏
  • optimize 回收表空间的一些说明

    线上服务器,有张大表需要用pt-archiver根据时间划分归档大量数据到另一个新表中。原先200G的表,在归档完成后,du -hs 显示依然是200G的大小,...

    二狗不要跑
  • 文件系统和裸块设备的page cache问题

    文件系统读取文件一般会使用do_generic_file_read(),mapping指向普通文件的address space。如果一个文件的某...

    Linux阅码场
  • django 分页

    https://www.jianshu.com/p/77a8ea421e22 https://blog.csdn.net/weixin_42134789/ar...

    以谁为师
  • Django自定义分页

    py3study
  • CRM之分页

      分页功能在网页中是非常常见的一个功能,其作用也就是将数据分割成多个页面来进行显示。

    py3study
  • 13.Django基础之django分页

      我们使用脚本批量创建一些测试数据(将下面的代码保存到bulk_create.py文件中放到Django项目的根目录,直接执行即可。):

    changxin7

扫码关注云+社区

领取腾讯云代金券