新浪微博爬虫阶段总结

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

相关文章

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

Nginx Location映射规则总结归纳与最佳实践

《NginxLocation映射规则总结归纳与最佳实践》Nginx的location指令是配置请求路由的核心机制,其匹配规则直接影响请求的处理流程,下面给大家介绍NginxLocation映射规则... 目录一、Location匹配规则与优先级1. 匹配模式2. 优先级顺序3. 匹配示例二、Proxy_pa

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

MySQL基本查询示例总结

《MySQL基本查询示例总结》:本文主要介绍MySQL基本查询示例总结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Create插入替换Retrieve(读取)select(确定列)where条件(确定行)null查询order by语句li

MySQL中的两阶段提交详解(2PC)

《MySQL中的两阶段提交详解(2PC)》:本文主要介绍MySQL中的两阶段提交(2PC),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录引言两阶段提交过程sync_binlog配置innodb_flush_log_at_trx_commit配置总结引言在Inn

Linux区分SSD和机械硬盘的方法总结

《Linux区分SSD和机械硬盘的方法总结》在Linux系统管理中,了解存储设备的类型和特性是至关重要的,不同的存储介质(如固态硬盘SSD和机械硬盘HDD)在性能、可靠性和适用场景上有着显著差异,本文... 目录一、lsblk 命令简介基本用法二、识别磁盘类型的关键参数:ROTA查询 ROTA 参数ROTA

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

Windows Docker端口占用错误及解决方案总结

《WindowsDocker端口占用错误及解决方案总结》在Windows环境下使用Docker容器时,端口占用错误是开发和运维中常见且棘手的问题,本文将深入剖析该问题的成因,介绍如何通过查看端口分配... 目录引言Windows docker 端口占用错误及解决方案汇总端口冲突形成原因解析诊断当前端口情况解

java常见报错及解决方案总结

《java常见报错及解决方案总结》:本文主要介绍Java编程中常见错误类型及示例,包括语法错误、空指针异常、数组下标越界、类型转换异常、文件未找到异常、除以零异常、非法线程操作异常、方法未定义异常... 目录1. 语法错误 (Syntax Errors)示例 1:解决方案:2. 空指针异常 (NullPoi