前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python分布式微博爬虫(源码分享)

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

作者头像
小歪
发布2018-04-04 14:20:49
1.3K0
发布2018-04-04 14:20:49
举报

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

关于本项目

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

你可以用它来干嘛

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

为何选择本项目

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫与算法进阶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于本项目
  • 你可以用它来干嘛
  • 为何选择本项目
  • 项目结构
  • 配置和使用
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档