爬虫软件python彻底卸载_Python爬虫实践:如何优雅地删除豆瓣小组的帖子

前言

文章起源于自己的一个需求:想要删除掉自己的若干个小号在豆瓣小组上的发帖及回复记录。这是一件看似简单的事情,但是一遍一遍的重复操作实在让我感到非常绝望,特别是删除自己的回复时,有时候回复的帖子的回复有好几十页,得一页一页的翻。于是就想到用脚本来代替人力操作。对于一名职业为前端工程师的人而言,最容易想到的方法就是打开DevTools发个Ajax请求直接搞定了。不过经历过几次之后发现这种方法很难沉淀下来,于是就想能不能写到脚本里面。一开始依旧想到的是用NodeJS来实现,但是由于最近由于接触程序化交易比较多,发现如果再不温习一下Python大蟒蛇又要忘光了,于是就想借机同时练练Python。

结果

先说结果

安装

两种方式:

源代码已放到github,可自行查看下载:https://github.com/acrazing/dbapigit clone https://github.com/acrazing/dbapi.git

cd dbapi

# 安装依赖

pip install -r requirements.txt

包已发布到pip,可自行安装:pip install dbapi

使用

首先得安装,然后:

登录客户端:因为客户端有缓存Session,所以你只需要登录一次,在命令行中:python -m dbapi.DoubanAPI test_client login "username" "password"

删除自己回复过的帖子:因为要删除自己发的帖子实际上是要删除掉所有自己在帖子下的回复,如果回复非常多不知道自己回复的在哪一页或者自己的回复非常多,操作起来会比较恶心python -m dbapi.DoubanAPI test_api remove_commented_topic "topic_id"

# topic_id 可以通过下面这个命令拿到:

python -m dbapi.DoubanAPI test_api list_commented_topics

# 这个命令会返回所有自己回复过的帖子

删除自己发的帖子:因为要先删除所有的回复,所以也很恶心python -m dbapi.DoubanAPI test_api remove_topic "topic_id"

# topic_id 可以通过下面这个命令拿到:

python -m dbapi.DoubanAPI test_api list_user_topics

# 这个命令会返回所有自己发布的帖子

需求分析

首先需求很明确:快速删除掉在豆瓣小组内的发帖和回复记录

要访问自己的豆瓣小组,需要登录帐号获取会话信息,其中一个关键的信息会话IDdbcl2设置了HttpOnly,此外还需要一个动态idck。当然这些问题都可以通过把所有的Cookie添加到客户端搞定。

要删除发帖记录,需要先删除掉贴子下的所有回复,在删除别人的回复时,需要调用管理员权限并提交理由

要删除掉回复记录,需要删除掉所有的自己的回复,但是别人的引用是无法删除的,所以最后要真正隐藏掉记录,需要注销帐号。

登录是敏感操作,频繁登录很容易触发机器人,需要缓存会话信息

访问频率过高也会触发机器人,需要做访问限制

接口列表

通过浏览器抓包发现,相关操作主要有几下几个接口:

登录账号:POST https://www.douban.com/accounts/login,登录前需要先获取bid等信息,登录时如果不设置redir_url,会自动跳转到豆瓣首页,如果登录失败,则不会跳转,可以据此判断登录是否成功,或者也可以用Cookie信息进行判断。跳转完成后会拿到所有会话所需要的Cookie信息,所以需要跟踪跳转

登出账号:GET https://www.douban.com/accounts/logout?source=group&ck=%s,这里的ck就是会话中的ck

获取自己发的帖子列表:GET https://www.douban.com/group/people/%s/publish,有翻页

获取自己回复过的帖子列表:GET https://www.douban.com/group/people/%s/reply,有翻页

删除自己的回复:POST https://www.douban.com/j/group/topic/%s/remove_comment

删除自己发的帖子下的别人的回复:POST https://www.douban.com/group/topic/%s/remove_comment

此外还有一些已实现但是与此无关的接口,可以到代码中dbapi/endpoints.py中查看

接口设计

为了方便扩展,封装了一层基础的API SDK:只是对单个页面进行请求及信息提取,所有的其它上层操作都基于这个SDK,比如删除发帖记录等

为了方便扩展,对接口进行了模块化处理:比如豆瓣小组Group,用户People等模块等

为了方便调用,封装了一个统一的出口类DoubanAPI,对会话缓存,登录登出等操作进行统一管理,并引入了各个模块

对于每个网络请求,需要用到公共头及会话信息,所以封装了一个基类BaseAPI统一网络请求,并且返回数据有可能是html或者json,所以提供了三个相关接口,同时部分接口需要显式调用ck,所以提供了相关接口

依赖

网络请求由requests实现

大部分read接口返回的数据都是html格式,这里使用lxml及xpath进行读取

使用logging输出日志

代码分析

略,请参考源代码

其它

除了小组相关API外,还实现了用户People相关的部分API,可以实现获取用户profile,关注用户及关注者,代码在dbapi/People.py中。利用这几个API设计了一个多线程爬虫,用来爬取豆瓣上的热门用户,代码在test/relation.py中,爬取的结果放在__relation__.json中。目前我注册了4个豆瓣账号,开了4个线程进行爬取。最开始由一个种子用户sevear,爬取其关注的用户中关注者大于100的用户,然后逐渐将关注者最小值加到现在的10000。目前已发布到Github的结果中,已经爬取了33599个用户,其中1069个用户的关注者超过了10000。发现了一些比较有趣用户,比如熊阿姨等;也发现热门的用户大多都会贴上自己的微信公众号,微博等信息;还有很多从05年就开始使用豆瓣的重度用户,也有很多注销了的账号。虽然我也很多年前就注册了豆瓣,但是一直没有发现除了发租房贴,看电影评价,听FM(现在已经不用了)之外还有什么其它价值。也许这些人可以给我答案。

总结

因为之前对Python的了解仅限于语法层面,未接触过相应的生态,比如pip包管理,setuptools等,并且不熟悉相关的基础包。所以几乎得从零开始,是件很头疼的事情,所幸的是Python的包都比较有名气,包管理等网络上也有很多教程,查找起来都比较容易。感谢互联网~

通过test/relation.py测试发现,目前存在内存泄漏问题,但是捣鼓了半天没有查到问题所在,已经没有兴趣继续花时间了~

同上,访问频率过高有可能会触发IP封禁,出现Please try later以及检测到你的IP有非正常请求发出balabala提示~

同上,现在4个线程中每个请求之前间隔时间调整到了3秒,再也没有出现IP封禁的提示~

客户端架构存在很大问题:比如无法动态更新会话信息,频繁获取模块有额外的性能开销等,需要重新设计整体架构,同样已经没有兴趣了,等以后有心情再更新吧~

分不清账号和帐号, 帖子和贴子,求语文老师

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/352182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高斯卷积核如何生成 C语言实现

对于学图像专业的人来说,对图像进行高斯滤波应该不会陌生,本质上就是将图像与高斯核进行卷积。 但是高斯核是如何生成的呢。matlab中有函数能自动生成高斯卷积核: gsfspecial(gaussian,3,1) gs 0.0751 0.1238 0.0751 0.1238 0.…

连接MySQL数据库时常见故障问题的分析与解决

连接MySQL数据库时常见故障问题的分析与解决 初学的mysql网友好象经常会碰到mysql无法连接的错误。特开贴收集这样问题的现象和原因。 先自己扔块砖头出来。 归纳如下: 故障现象 : 无法连接 mysql 错误信息1 :ERROR 1045 (28000): Access deni…

如何判断两个平面相交_七年级下册相交线与平行线全章节复习

5.1 相交线(一)相交线两条直线相交,形成4个角。1、两条直线相交所成的四个角中,相邻的两个角叫做邻补角,特点是两个角共用一条边,另一条边互为反向延长线,性质是邻补角互补;相对的两个角叫做对顶角&#xf…

spring dao层注解_Spring– DAO和服务层

spring dao层注解欢迎来到Spring教程的第三部分。 在这一部分中,我们将继续编写Timesheet应用程序,这次我们将实现DAO层,业务服务并编写一些测试。 在上一部分中,我们定义了GenericDao接口,该接口告诉我们需要对实体执…

Word 2007 如何自动生成目录以及设置正文第一页?

首先,讲解如何生成目录。 第一步,设置目录的小结的题目。这个需要对一级标题,二级标题,三级标题进行设置,设置方法如下图所示: 可以点击右键,对标题的格式进行修改。 第二步,直接生成…

python 优先队列_python中使用优先队列

相信对于队列的概念大家都不会陌生,这种先入先出的数据结构应用很广泛,像一般的生产消费都会用到队列,关于Queue的用法介绍可以参考我之前的文章 python中的Queue与多进程(multiprocessing)还有栈,栈是一种…

JHipster入门,第2部分

所以你回来了! 在本系列的最后一部分中 ,我们采用了单片路线创建了一个JHipster应用程序。 这是红色药丸路线; 生活与您习惯的差不多。 但是也许您喜欢挑战。 也许您想超越红色药丸并尝试蓝色药丸。 在这种情况下,Blue Pill是微服…

由于html元素加载导致的问题

js中要求执行的事件是在完全加载完,但由于本地环境测试一直没发现出问题,在上线后由于网络延迟导致元素加载慢,而事件执行完,没达到预期目标。 这时就需要用到属性 readyState readyState 属性返回当前文档的状态(载入…

Linux下MySQL数据库常用基本操作 一

1、显示数据库 show databases; 2、选择数据库 use 数据库名; 3、显示数据库中的表 show tables; 4、显示数据表的结构 describe 表名; 5、显示表中记录 SELECT * FROM 表名 6、建库 create databse 库名; 7、建表 create table 表名 (字段设定列表);mysql> cr…

C语言读取txt文档中的数据

1.说明 txt文档中的数据格式:前后数据用空格隔开;数据来源:matlab读取彩图的R、G、B三层的像素值,分别存放在三个txt文档中,用C读取到一维数组。动态申请数组,还是需要预先知道数组的大小,比静态…

cpickle支持的python版本_Python序列化模块pickle和cPickle

Python的序列化是指把变量从内存中变为可以储存/传输的数据/文件的过程. 在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后,就可以把序列化后的内容写…

Intellij IDEA 4种配置热部署的方法

Intellij IDEA 4种配置热部署的方法 热部署可以使的修改代码后,无须重启服务器,就可以加载更改的代码。 第1种:修改服务器配置,使得IDEA窗口失去焦点时,更新类和资源 菜单Run -> EditConfiguration , 然后配置指定服…

mysql启动报错:Another MySQL daemon already running with the same unix socket.

[rootlocalhost ~]#/etc/init.d/mysqld restart Stopping mysqld: [ OK ] Another MySQL daemon already running with the same unix socket. Starting mysqld: [FAILED] 原因多个Mys…

malloc申请一维动态数组的错误

正确写法:int *tmp ( int * )malloc( H*W*sizeof(int) ); float *tmp ( float * )malloc( H*W*sizeof(float) ); double *tmp ( double * )malloc( H*W*sizeof(double) ); 错误写法:double *tmp ( double * )malloc( H*W*sizeof(double * ) ); 错…

java检查注入sql框架_Java:检查器框架

java检查注入sql框架我在JavaOne 2012上 了解的有趣的工具之一是Checker Framework 。 Checker Framework的网页之一 指出 ,Checker Framework“增强了Java的类型系统,使其更加强大和有用”,从而使软件开发人员“能够检测并防止Java程序中的错…

jqc3ff继电器引脚图_电气元件中间继电器的知识全面解读,欢迎电工朋友收藏!...

继电器(英文:Relay),也称电驿,是一种电子控制器件,它具有控制系统(又称输入回路)和被控制系统(又称输出回路),通常应用于自动控制电路中,它实际上是用较小的电流去控制较大电流的一种“自动开关”。故在电路…

]remove-duplicates-from-sorted-list-ii (删除)

题意略&#xff1a; 思路都在注解里&#xff1a; #include<iostream> #include<cstdio> using namespace std;struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}};class Solution {public:ListNode *deleteDuplicates(ListNode *h…

C语言动态数组建立方法

动态数组是指在声明时没有确定数组大小的数组&#xff0c;即忽略圆括号中的下标&#xff1b;当要用它时&#xff0c;可随时用ReDim语句&#xff08;C语言中用malloc语句&#xff09;重新指出数组的大小。使用动态数组的优点是可以根据用户需要&#xff0c;有效利用存储空间。 动…

Linux小宝典之理解Chroot模式

Chroot 在 Linux 系统中发挥了根目录的切换工作&#xff0c;同时带来了系统的安全性等好处。本文通过编写 chroot 来理解 chroot 的作用和好处&#xff0c;这不仅有助于更好的使用 chroot&#xff0c;同时加深了对 Linix 系统初始 RAM 磁盘工作的认识。 chroot&#xff0c;即 …

jHipster入门,第1部分

因此&#xff0c;您想保持技术的领先地位&#xff0c;但对所有活动部件感到不知所措。 你真幸运&#xff01; 这是jHipster发光的地方。 如果您喜欢Ruby on Rails或Grails的方法来快速启动和运行应用程序&#xff0c;那么这可能是适合您的选择。 jHipster旨在使设置应用程序变…