Python豆瓣机器人(模拟登录,发广播,发帖,发豆邮,抢沙发)

# 背景

害羞组里有一个"王叔叔"各种抢沙发.好像很屌的样子,so,作为一名伪Geek,怎么会不想自己出一个呢.


# 功能

  1. 模拟登录(Cookies)
  2. 发广播
  3. 发帖
  4. 抢沙发
  5. 发豆邮

# 分析

豆瓣其实是有官方API的.但是其实功能做了很多限制,为了限制各种垃圾信息,比如豆瓣小组就没有,发豆邮什么的就不要想了.

首先得弄清楚HTTP协议,自行Google.

所以我们只能采用爬虫模拟浏览器操作这些过程.比如我们登录是向<http://www.douban.com/accounts/login POST>方式提交账号密码数据.

这里我通过使用Chrome 自带的开发者工具就可以看到POST的数据。

这里我获取的是登录的POST表单。

login

相应的其他也可以相应的方式获得.

这是发广播的: talk ....

得到这里东西之后,我们只需要POST相应的数据,就可以完成登录发广播,发豆邮等操作.


# 实现细节

# 模拟浏览器

基本的打开一个网页:

import urllib.request
url = "https://linsir.org"
html = urllib.request.urlopen(url).read()
print(html)

如果不加User-Agent,则有些网址的访问,会被禁止的,所以我们应该这样:

#! /usr/bin/env python
# -*- coding=utf-8 -*- 

import urllib.request

url = "https://linsir.org"
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Accept':'text/html;q=0.9,*/*;q=0.8',
'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Accept-Encoding':'gzip',
'Connection':'close',
'Referer':None 
}
opener = urllib.request.build_opener()
opener.addheaders = [headers]
html = opener.open(url).read()
print(html)

# Cookies操作

带上Cookies登录后的操作就可以顺利的进行,否则会被服务器拒。 这里可以参考之前的Python 爬虫Cookie的处理

# 登录

POST数据可以这样子操作:

self.data = {
                "form_email": email,
                "form_password": password,
                "source": "index_nav",
                "remember": "on"
}  
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookieJar));
response = opener.open(self.login_url, urllib.urlencode(self.data))

# 验证码

当这个账号在非常用登录地或者账号短时间连续登录或密码错误的时候,就会触发验证码机制。 解决方法:

  1. Cookies记住登录
  2. 破解或手工输入

验证码破解,我并没深入研究,豆瓣的又不会那么容易破解。我解决方法是如果有验证码,手工输入,然后保存Cookies,下次直接用Cookies操作,直到Cookies过期。

imgurl = re.compile(r'<img id="captcha_image" src="(.+?)" alt="captcha"').findall(html)
if imgurl:
    #download the captcha_image file.
    # urllib.urlretrieve(imgurl[0], 'captcha.jpg')
    print "the captcha_image address is %s" %imgurl[0]
    data = opener.open(imgurl[0]).read() 
    f = file("captcha.jpg","wb")  
    f.write(data)  
    f.close()

# 获得ck值

通过分析,登录后的操作,每次提交的数据中都有一个ck字段,所以我们要在登录后找到这个值。我发现一旦登录后网页的源代码中会有ck值,另外Cookies里也会有ck的值,所以通过正则在源代码中获取,或者直接在cookies里读取,随便哪一种都 行。我这里采取后者。

def get_ck(self):
    #open a url to get the value of ck.
    self.opener.open('http://www.douban.com')
    #read ck from cookies.
    for c in list(self.cookie):
        if c.name == 'ck':
            self.ck = c.value.strip('"')
            print "ck:%s" %self.ck
            break

# 发广播,发豆邮,发贴子,回贴子

登录后的操作就非常的简单了,只需要向特定的url提交相应符合规范的数据即可。 比如,发广播:

def talk_statuses(self, content = '(⊙o⊙)…'):

    post_data = urllib.urlencode({
        'ck' : self.ck,
        'comment' : content,
        })

    request = urllib2.Request("http://www.douban.com/")
    # request.add_header("Origin", "http://www.douban.com")
    request.add_header("Referer", "http://www.douban.com/")
    self.opener.open(request, post_data)

# 抢沙发

原理很简单,刷新页面用正则找出回复为0的帖子的topicid,然后调用回贴即可。

回复的内容可以随机选择一个。


def sofa(self,
    group_id,
    content=['丫鬟命,公主心,怪不得人。', 
            '要交流就平等交流,弄得一副跪舔样,谁还能瞧得起你?',
            '己所欲,勿施于人..',
            '人在做,天在看.',]
    ):

    group_url = "http://www.douban.com/group/" + group_id +"/#topics"
    html = self.opener.open(group_url).read() 
    topics = re.findall(r'topic/(\\d+?)/.*?class="">.*?<td nowrap="nowrap" class="">(.*?)</td>',
                html, re.DOTALL)

    for item in topics:
        if item[1] == '':
            post_data = urllib.urlencode({
                    "ck" : self.ck,
                    "rv_comment" : random.choice(content),
                    "start" : "0",
                    "submit_btn" : "加上去"
            })
            self.opener.open("http://www.douban.com/group/topic/" + item[0] + "/add_comment#last?", post_data)
 



# 测试

new_talk

成功发了个广播.


# 不足

  1. 验证码难绕过:在短时间内,如果发豆邮或者回贴次数过高,会触发豆瓣的机器人识别机制,回贴或其他操作时会要求输入验证码。当然这也是为了减少垃圾信息。
  2. 抢沙发没有多线程,可能慢一点就是二楼了。不过多线程被豆瓣秒封的节奏。

# 总结

所谓的这个机器人,实际上就是模拟人用浏览器操作一些行为。在这过程过有很多坑,这里可以参考这篇博客的总结:【总结】静态网页抓取,动态网页抓取,模拟登陆的注意事项和心得


# 源代码

太长了,直接贴Github了:

https://github.com/vi5i0n/doubanrobot


参考地址:

  1. 【总结】静态网页抓取,动态网页抓取,模拟登陆的注意事项和心得

--EOF--


>看不到评论?GFW!!!