利用scrapy登录豆瓣

一、网页分析

img

豆瓣的登录页面如上,如果你是第一次登陆是不需要输入验证码的,当多次登录失败后将出现验证码。

点击登录并抓包,得到如下的参数

img

其中form_email和form_password分别是用户名和密码,captcha-solution是输入的验证码, captcha-id为验证码id, 在对登录网址进行get请求时可以得到

img

这样我们就能大概有了一个思路:

首先get请求登录页面, 若有验证码则保存本地, 并提取出captcha-id, 之后post请求登录页,完成登录过程, 若无验证码则直接发送post请求。整体流程没有难度, 所有字段都是明文,没有任何加密。

二、代码实现

scrapy的项目结构如下:

img

编写start.py脚本用于启动scrapy:

1
2
3
4
from scrapy import cmdline

if __name__ == '__main__':
cmdline.execute('scrapy crawl db'.split())

主要代码db.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import scrapy
from PIL import Image
import urllib
class DbSpider(scrapy.Spider):
name = "db"
# allowed_domains = ["douban.com"]
start_urls = (
'https://accounts.douban.com/login',
)

def parse(self, response):
captcha =response.xpath("//img[@id='captcha_image']/@src").extract_first()
if captcha:
print captcha
print 'find captcha...'
urllib.urlretrieve(captcha, 'captcha.jpg')
Image.open('captcha.jpg')
cap = raw_input('input captcha manually:')
captcha_id = response.xpath("//input[@name='captcha-id']/@value").extract_first()
print captcha_id
yield scrapy.FormRequest(
url='https://accounts.douban.com/login',
formdata={
'source': 'None',
'redir': 'https://www.douban.com /',
'form_email': 'xxxxxxxx',
'form_password': 'xxxxxxxx',
'login': '登录',
'captcha-solution': cap,
'captcha-id': captcha_id
},
callback=self.parse_after_login,
)
else:
print 'no captcha'
yield scrapy.FormRequest(
url='https://accounts.douban.com/login',
formdata={
'source': 'None',
'redir': 'https://www.douban.com /',
'form_email': 'xxxxxxx',
'form_password': 'xxxxxx',
'login': '登录',
},
callback=self.parse_after_login,
)


def parse_after_login(self, response):
print response.url
if 'caelansar' in response.body: # 如果用户名在页面中,则登录成功
print 'login success'
else:
print 'fail'

需要注意的是,必须要在setting中设置USER_AGENT, 否则访问登录页将出现403错误。