Python爬虫模拟登录pixiv

Last updated on

记录学习Python模拟登录的过程


需要的工具及运行环境

  • Python 3.6
  • requests 库
  • re 库
  • Chrome 浏览器

分析URL

进入pixiv官网,
按F12 开打开发者工具界面,点击官网上的LOGIN 按钮,
跳转到登录界面,
开发者工具界面依次选择“Network”->“Doc”,左侧Name栏有请求信息。

如图可知三个重要信息:

  • 请求方式:GET
  • User-Agent
  • get的请求参数
构建请求headers
1
headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36'}
构建请求参数
1
2
3
4
5
6
params ={
'lang': 'en',
'source': 'pc',
'view_type': 'page',
'ref': 'wwwtop_accounts_index'
}

尝试登录

开发者界面,勾选Preserve log。

输入账号,密码登录pixiv
开发者工具界面点击“XHR” ,左侧name栏选择“login?lang=en”

获得信息:

  • 发送表单方法post
  • 表单中要发送的数据
构建要发送数据的字典
1
2
3
4
5
6
7
8
9
10
datas = {
'pixiv_id': 'yourEmail@123.com',
'password': 'yourpassword',
'captcha': '',
'g_reaptcha_response': '',
'post_key': '',
'source': 'pc',
'ref': 'wwwtop_accounts_indes',
'return_to': 'https://www.pixiv.net/'
}

注意到字典中有一个key 为post_key,这个东西你每次登录之前会给你个唯一值,所以我们要获得这个值,并将赋值给post_key的value。
进入登录界面,F12进入开发者工具界面,选择Elements,ctrl+F 搜索”form”标签

建立匹配规则
1
pattern = re.compile(r'name="post_key" value="(.*?)">')

完整代码

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
# -*- coding=utf-8 -*-
import requests
import re

headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36'}

# get提交参数
params ={
'lang': 'en',
'source': 'pc',
'view_type': 'page',
'ref': 'wwwtop_accounts_index'
}

# post提交参数
datas = {
'pixiv_id': 'yourEmail@123.com',
'password': 'yourpassword,
'captcha': '',
'g_reaptcha_response': '',
'post_key': '',
'source': 'pc',
'ref': 'wwwtop_accounts_indes',
'return_to': 'https://www.pixiv.net/'
}

login_url = 'https://accounts.pixiv.net/login' # 登陆的URL
post_url = 'https://accounts.pixiv.net/api/login?lang=en' # 提交POST请求的URL

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

# 获取登录页面
res = s.get(login_url, params=params)

# 获取post_key
pattern = re.compile(r'name="post_key" value="(.*?)">')
r = pattern.findall(res.text)
datas['post_key'] = r[0]

# 模拟登录
result = s.post(post_url, data=datas)

# 打印出json信息
print(result.json())

2017.5.16 完善代码

  • 学习了cookie的使用,若第一次登陆成功,下次登录后就可以使用cookie登录了。
  • 将完整的代码进行了封装。
  • 增加了交互式
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    # -*- coding=utf-8 -*-
    import requests
    import re
    import http.cookiejar

    class PixivSpider(object):
    def __init__(self):
    self.session = requests.Session()
    self.headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36'}
    self.session.headers = self.headers
    self.session.cookies = http.cookiejar.LWPCookieJar(filename='cookies')
    try:
    # 加载cookie
    self.session.cookies.load(filename='cookies', ignore_discard=True)
    except:
    print('cookies不能加载')

    self.params ={
    'lang': 'en',
    'source': 'pc',
    'view_type': 'page',
    'ref': 'wwwtop_accounts_index'
    }
    self.datas = {
    'pixiv_id': '',
    'password': '',
    'captcha': '',
    'g_reaptcha_response': '',
    'post_key': '',
    'source': 'pc',
    'ref': 'wwwtop_accounts_indes',
    'return_to': 'https://www.pixiv.net/'
    }

    def get_postkey(self):
    login_url = 'https://accounts.pixiv.net/login' # 登陆的URL
    # 获取登录页面
    res = self.session.get(login_url, params=self.params)
    # 获取post_key
    pattern = re.compile(r'name="post_key" value="(.*?)">')
    r = pattern.findall(res.text)
    self.datas['post_key'] = r[0]

    def already_login(self):
    # 请求用户配置界面,来判断是否登录
    url = 'https://www.pixiv.net/setting_user.php'
    login_code = self.session.get(url, allow_redirects=False).status_code
    if login_code == 200:
    return True
    else:
    return False

    def login(self, account, password):
    post_url = 'https://accounts.pixiv.net/api/login?lang=en' # 提交POST请求的URL
    # 设置postkey
    self.get_postkey()
    self.datas['pixiv_id'] = account
    self.datas['password'] = password
    # 发送post请求模拟登录
    result = self.session.post(post_url, data=self.datas)
    print(result.json())
    # 储存cookies
    self.session.cookies.save(ignore_discard=True, ignore_expires=True)

    if __name__ == "__main__":
    spider = PixivSpider()
    if spider.already_login():
    print('用户已经登录')
    else:
    account = input('请输入用户名\n> ')
    password = input('请输入密码\n> ')
    spider.login(account, password)