怎么像瓦力酱和隔壁王叔叔那样在豆瓣抢沙发?

技术 赵有财 4036℃ 0评论

经常上豆瓣的文青不知道有没有看到“瓦力酱”老是抢沙发呢?以前我也觉得很神奇,好像说秒回的,不知道它手这么快,经过慢慢的了解了才知道,瓦力酱原来是一机器人,都不搭理人的,类似的还有“王叔叔”之类的,姑且叫它们“抢沙发程序吧”,这个疑问一直没有答案,但心中早已种下了“要做一个抢沙发机器人”的,但苦于如何实现,没有人指导,百度也没答案。如今,学习了Python,答案慢慢的浮出来了。

瓦力酱 隔壁王叔叔 是怎么做到的?

当然了,我不是瓦力酱,不可能真正知道它是如何实现的,但是基本的方法可以应该差不多的。

1、模拟用户登录
要发表回复肯定是要登录才行,而且要维持登录状态,最好处于同一个Session,这样才不容易被反爬虫的重新屏蔽,这个过程可能会要输入验证码。
2、监控
首先得监控小组的主题列表页面,不管它是监控各个小组的,还是就是监控“小组”那个页面,都是要找到刚刚发布的,0回复的主题。然后就要间隔一定的时间刷新页面,重新获取页面中0回复的主题。
3、发表回复
经过监控主题列表,找到了0回复的主题要赶紧回复抢沙发喽,就要模拟用户提交数据,和登录的过程差不多。

4、循环
除了登录意外,整个刷新页面,获取0回复主题,发表回复,这几个步骤说要一直循环自动执行的,不然就不能说是机器人了。

代码实现抢沙发

大致了解整个过程后就是如何来实现啦。经过上一次在《Python入门学习:使用http.cookiejar生产Cookie模拟用户登陆》中写的模拟登录,也测试过了登录豆瓣的,但是由于换了个环境,基本的原理差不多的,不过所有代码要重现敲了。

环境

操作系统:OS X Yosemite(版本 10.10.5 )

Python版本:2.7.10

外部库:BeautifulSoup4、requests

完整代码:https://github.com/zhaoyoucai/robot/blob/master/doubanrobot.py

(一)重写Python实现模拟用户登录

和《Python入门学习:使用http.cookiejar生产Cookie模拟用户登陆》中不一样的是这次使用了requests库,因为在Python 3.4版本中安装BeautifulSoup4一直都搞不定,所有就干脆在Python 2.7来,还有好多好用的库又可以用起来了。

1、创建会话对象

首先还是得构造一个字典数据结构的header用于模拟登录的时候Session使用

headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, compress',
'Accept-Language': 'zh-CN,zh;q=0.8',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36'}

s = requests.Session()
s.headers.update(headers)

这里首先需要了解Session的概念,Session即会话,简单理解就是允许通过将对象存储在 Web服务器的内存中在整个用户会话过程中保持任何对象,当一个session第一次被启用时,一个唯一的标识被存储于本地的cookie中。会话对象让我们能够跨请求保持某些参数,我们需要在同一个Session实例发出的所有请求之间保持cookies。使用requests可以轻松的创建Session对象:requests.Session() [参考:http://cn.python-requests.org/en/latest/user/advanced.html]

另外我们可以使用update方法将header数据追加到会话对象的header消息头中,有点类似之前的Opener对象的addheaders。

以上我们就完成一个会话创建与初始化工作,后面的访问请求都是基于这个会话,并保持整个会话的相关参数直到结束。

2、访问首页获取验证码与初始化登录数据

我选择重首页开始访问登录,需要基本的数据,开始可能不需要输入验证码,但是访问多了就需要了,所有这里要请求后把验证码的图片URL打印出来,等待接受输入验证码,手动在浏览器打开图片识别验证码后输入,程序继续执行。这样登录所需的数据就准备齐全了。关于BeautifulSoup的使用,可以参考《Python入门学习:Beautiful Soup 4检查页面TDKH标签》,需要详细的使用文档参考:http://www.crummy.com/software/BeautifulSoup/bs4/doc/

代码片段如下:

r1 = s.get(URL_HOME)
sp = BeautifulSoup(r1.content)
captcha_id = sp.find(attrs={"name": "captcha-id"}).get('value')
captcha_image = sp.find('img','captcha_image').get('src')
print(captcha_image)
captcha_solution = raw_input("输入验证码:\n")
login_data={
'source':'index_nav',
'form_email':'g******[email protected]',
'form_password':'********',
'captcha-solution':captcha_solution,
'captcha-id':captcha_id,
'remember':'on'
}

执行中会要求输入验证吗,如下图:

打印验证码图片链接,暂停输入验证

这样登录所需的数据准备好了之后,写在一个字典数据中,完成初始化,已备登录提交使用。

3、提交登录获取主题列表页面

s.post(URL_LOGIN,data=login_data)
r = s.get(URL_GROUP)

非常简单,提交数据使用post方法,访问获取页面数据使用get方法。正常登录成功之后访问的http://www.douban.com/group/会说正常的,未登录成功则是会302重定向至http://www.douban.com/group/explore。

(二)监控与循环

成功登录并获取主题列表后就要循环刷新监控这个页面的0回复主题,整个过程循环很简单:

if r.url != URL_GP_EXPlORE:
print('登录成功...\n')
html = r.content
soup = BeautifulSoup(html)
topics = soup.find('div','topics')
topics = topics.find_all('tr','pl',limit=50)
for topic in topics:
subject = topic.find('td','td-subject').a.get('href')
reply = topic.find('td','td-reply').get_text()
sum = re.findall("\d+", reply)
sum = int(sum[0])
if sum < 1:
print('go to reply...')
......
time.sleep(random.randrange(120,180))
r = s.get(URL_GROUP)
print(time.strftime("%Y-%m-%d %H:%M:%S"))

(注意:代码缩进被打乱了)

代码也不复杂,整个逻辑清楚就好,再次需要使用BeautifulSoup,提取页面的标签元素非常方便,主要提取啦主题的URL、主题的回复数,另外其他的回复时间、小组等暂时不用就不必要获取了,省点时间。另外一个重要的地方是:

sum = re.findall("\d+", reply)

使用了正则表达式来提取“0回复”中的数字部分,好进行处理。判断回复数小于1就是可以抢沙发到主题,提取URL后进行后续的回复操作。

抢完一轮沙发后,暂停一定时间再刷新页面,再使用:

r = s.get(URL_GROUP)

重新获取页面内容即可。

(三)发表回复抢沙发

这个是重点,但是却也很简单,很登录的过程差不多,就是一个提交表单的操作:

if sum < 1:
 print('go to reply...')
 print(subject)
 t = s.get(subject)
 s.post(subject+URL_COMMENT,data = randCommnet())

上面提交表单的数据使用了一个随机生成的函数,是因为怕回复内容都一样容易被揪,所以会从一个回复内容列表中随机提取一个来回复,函数代码类似《Python入门学习:应用random函数随机生成HTTP请求headers信息》中随机生成一个header的过程,代码就不贴了,参考全部代码到我的Github账号。

看一下成果吧:

豆瓣抢沙发

时间虽然不是秒回,但抢沙发才是重点,还好没被怀疑是机器人哈,就这样和瓦力酱跟隔壁王叔叔差不多了。

另外需要注意,如果被反机器人机制识别了,即使登录了,回复还是要输入验证码的,回复不成功没有提示,暂时没去解决,要是以后能写识别图片中等验证码那就好了(好难啊!)

转载请注明:「知而不乎」 » 怎么像瓦力酱和隔壁王叔叔那样在豆瓣抢沙发?

喜欢 (528)or分享 (0)
如果你觉得这篇文章还有价值,对你有帮助,请支持我继续更新 !捐赠本站

关注微信公众号

知而不乎微信公众号