新浪微博爬虫阶段总结

2024-06-15 00:48

本文主要是介绍新浪微博爬虫阶段总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,这是项目地址。
做这个爬虫的过程中,遇到了无数的坑,但是还好都填补上了,但是还是有几个问题实在是难以解决。暂时先记录如下。

  • MySQL的bug?python执行时传入了正确的语句,但是却出现了插入了错误的数据
  • 分属不同文件的消费者生产者不把队列赋值给类的属性,并作为参数传入子进程无法进行通信
  • cannot serialize _io.BufferedReader object问题总结反思

其中第一个问题应该是MySQL的设计问题,但是目前也没有找到原因,但是利用ignore倒是成功解决插入的主键冲突问题。
后两个问题很是奇葩,都是仅产生一次两次的问题,现在完全就不会有这个问题出现。所以我也不是很懂了,但是还是记录下来,这里面可能有什么地方存在着问题。

整体思路

对于这个爬虫项目,我是希望能够进行大规模的爬取,能够获取到较为大量的数据,所以一开始便需要对起进行一定的规划。因此,我将该爬虫划分为以下几个部分

  • Downloader 该部件主要用于下载数据,将数据传送到Spider中用于解析
  • Spider 该部件用于解析数据,然后将其放入数据库中‘
  • Database 显而易见,这是用于处理数据库的部件
  • Schedule 该部件用于从数据库中获取需要爬取的用户信息,然后构造网址进行爬取
  • transmission 这里包含了RequestResponse,这两个类封装了请求信息和获取到的信息,方便Spider进行归类整理
  • middlequeue 这一块用于存在数据传输的队列,方便不同的部件进行通信,直接利用了multiprocessingQueue
  • ErrorDeal 本来这个是用来处理请求失败的链接的,但是后来发现并不需要了,所以直接就扔了
  • ProxyCreate 该部件用于整理获取代理,但是因为各家的代理实在是太废了,然后发现了一家动态转发的代理服务商的服务不错,所以直接采用他家的服务,不再自己去获取代理。

这个爬虫的代码下载数据部分我采用的是多进程加协程进行请求,其他的部分直接利用单进程不断的循环便足够处理了。

分类

总结

新浪微博的数据在手机端可以免登录的获取,所以转战手机端。对于每个用户要获取其具体的粉丝关注者微博详情,需要知道各项的具体数量才能够进行页码构造。因此整个过程会比较绕。简要记为以下几点

  • 对于用户信息需要请求两个不同的网址才能够得到其完整信息,不过第二次所得到的信息并不十分重要,但还是一并获取了
  • 请求粉丝数据,关注者数据时,可以得到一定的用户信息,但是该信息会给假数据,所以只能从中获取到用户ID
  • 微博详情的数据中也可以获取到一定的用户信息,但是目前感觉这个部分的用户信息没啥意义,所以直接抛弃了
  • 利用触发器,将存入粉丝和关注者数据库中的ID都转存一份到用户详情数据库中
  • 对于用户详情数据库,利用一个冗余量来标记其目前的状态(具体在代码注释中有写),给Schedule提供调取信息
  • SpiderDownloader 中专门开一个进程用于用户信息的获取,防止用户信息的请求被堆积在各类请求中,导致后续无法进行网址构造
  • 种子用户即为我自己的微博账号
Downloader

Downloader这一部分,采用多进程加协程对请求进行处理,之前的测试速度是每秒钟MySQL增加12条记录,整体速度相应的还是比较慢,可能是开了太多进程的原因。代理采用的服务商的动态转发服务。
我将Downloader划分为两个部分

  • 用户详细信息下载进程 该进程仅用于下载用户的详细信息。当出现下载错误时,该Request再次进入下载队列,等待下一个下载
  • 粉丝关注者微博详情下载进程 该进程用于下载其他的信息,用info来统一标识,对于该进程的下载错误问题,将会进入一个错误队列,该错误队列直接进入Schedule,由Schedule安排下次下载

对于Downloader的错误错误问题,额外记录一个失败次数,一旦返回的数据长度小于500,且失败了一定次数后,便丢弃该Request。这里的失败次数暂时定为3次。有了这个规则在,对于info的具体页码制定规则便可以不用过多考虑。

Schedule

构造网址的工作交由Schedule处理。Schedule从数据库中获取用户详情和用户ID。将网址封装在Request中,传入请求队列。Schedule的工作分为以下三个部分

  • 用户信息请求单独放入一个Queue中
  • 用户详情信息请求放入另一个Queue中。为防止在某一固定时间段内总是在获取同一用户的某一信息。所以对于用户的粉丝关注者微博详情三种类别的请求,将随机取一小段放入队列中,直到所有信息请求网址都完全放入队列中
  • Schedule会接收从Downloader传过来的错误请求网址,每次将取一定的个数放入详情请求队列中
Spider

该部件用于解析新浪的json数据,并将其存入数据库中。该部件直接采用单进程的模式即可。
需要注意的事,对于微博详情的时间。只有刚发的微博的时间会显示出具体到分,而之前的时间都是到天。所以微博详情的时间一律以天为最小单位。

Database

数据库采用MySQL。需要注意的是,因为微博处于不断的动态变化,所以插入的数据可能会跟数据库中已有的数据产生冲突。我一开始采用的是ON DUPLICATE KEY UPDATE语句来防止冲突,后来发现该语句会导致数据库产生奇怪的数据问题,见上文链接,后来在别人的博客中发现了IGNORE这个关键词,可以有效的防止主键冲突问题。
后期需要的话,可能需要将数据库进行分表处理。目前主要的想法如下

  • 微博详情根据推文长度进行分表
  • 用户ID对应到一个序号,在各个表中仅存储ID序号

对于输入到粉丝数据表,关注者信息数据表的数据,将会有一个触发器将粉丝和关注者ID复制一份到用户信息数据库中,用于后续的抓取。

Log模块

为了方便记录各类信息,后面特意加上了日志记录。
但是出现了很奇怪的事。在DownloaderSpider模块里,如果在子进程里创建log对象,那么记录下载的日志信息将会出现重复的两条,对于这个问题也是很无解了。能发现这个原因是因为我发现Schedule的日志信息都不会有重复的出现,可是DownloaderSpider都会出现,于是觉得可能问题是出在了子进程的日志对象里。
于是便在类初始化时创建日志对象,之后直接调用,然后问题就得以解决。但是该问题的原因目前也不是很清楚。

后期规划

现在手上有两台服务器,所以打算将其做成一个分布式的爬虫。难点主要出现在,我觉得两台服务器都有50G的硬盘空间,如果不用来存东西感觉很是浪费。
为了保证不重复的抓取,我目前打算腾讯云的服务器用来做主机,阿里云的服务器用来做从机。阿里云的服务器存用户详情数据,对于从粉丝和关注者中得到的用户ID,通通发回给腾讯云的机子。腾讯云的机器一方面进行用户详情的获取,一方面也做用户粉丝关注者微博详情的获取。

整个分布式系统分为三个部分。

  • 分发系统。该系统用于发放需要抓取的用户详细信息
  • 用户信息完善系统。该系统分布于一台主机,用于完善用户信息
  • 各项信息抓取系统,该系统可以分布在多台机器上

这篇关于新浪微博爬虫阶段总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061958

相关文章

Python中实现进度条的多种方法总结

《Python中实现进度条的多种方法总结》在Python编程中,进度条是一个非常有用的功能,它能让用户直观地了解任务的进度,提升用户体验,本文将介绍几种在Python中实现进度条的常用方法,并通过代码... 目录一、简单的打印方式二、使用tqdm库三、使用alive-progress库四、使用progres

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Java向kettle8.0传递参数的方式总结

《Java向kettle8.0传递参数的方式总结》介绍了如何在Kettle中传递参数到转换和作业中,包括设置全局properties、使用TransMeta和JobMeta的parameterValu... 目录1.传递参数到转换中2.传递参数到作业中总结1.传递参数到转换中1.1. 通过设置Trans的

C# Task Cancellation使用总结

《C#TaskCancellation使用总结》本文主要介绍了在使用CancellationTokenSource取消任务时的行为,以及如何使用Task的ContinueWith方法来处理任务的延... 目录C# Task Cancellation总结1、调用cancellationTokenSource.

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;