新浪微博爬虫阶段总结

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

相关文章

Rust格式化输出方式总结

《Rust格式化输出方式总结》Rust提供了强大的格式化输出功能,通过std::fmt模块和相关的宏来实现,主要的输出宏包括println!和format!,它们支持多种格式化占位符,如{}、{:?}... 目录Rust格式化输出方式基本的格式化输出格式化占位符Format 特性总结Rust格式化输出方式

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo

Git提交代码详细流程及问题总结

《Git提交代码详细流程及问题总结》:本文主要介绍Git的三大分区,分别是工作区、暂存区和版本库,并详细描述了提交、推送、拉取代码和合并分支的流程,文中通过代码介绍的非常详解,需要的朋友可以参考下... 目录1.git 三大分区2.Git提交、推送、拉取代码、合并分支详细流程3.问题总结4.git push

Kubernetes常用命令大全近期总结

《Kubernetes常用命令大全近期总结》Kubernetes是用于大规模部署和管理这些容器的开源软件-在希腊语中,这个词还有“舵手”或“飞行员”的意思,使用Kubernetes(有时被称为“... 目录前言Kubernetes 的工作原理为什么要使用 Kubernetes?Kubernetes常用命令总

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