Python中使用urllib2模拟登录pixiv遇到了问题
使用的是 Python2+urllib2+cookielib 模拟登陆 pixiv,post 表单后尝试获取个人收藏页面但是得到的是 pixiv 的登录页面,怀疑是模拟登陆的过程有问题,排查了一天也没解决,实在不知道哪里错了。。求各位大手看一下,谢谢。。(账号和密码我给抹去了)
import re,urllib,urllib2
import cookielib
headers = {
‘Referer’: ‘https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index’,
‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; WOW64) ’
‘AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36’
}
request_loginpage = urllib2.Request(r’https://accounts.pixiv.net/login’)
getLoginPage = urllib2.urlopen(request_loginpage)
pattern = re.compile(r’<input type=“hidden” name=“post_key” value="(.*?)">’)
getPostKey = re.search(pattern,getLoginPage.read())
postKey = getPostKey.group(1)
print postKey
data = {
‘pixiv_id’:‘id’,
‘password’:‘password’,
‘post_key’:postKey,
‘return_to’:‘https://www.pixiv.net/’
}
cookie = cookielib.CookieJar()
handler=urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(handler)
encodeData = urllib.urlencode(data)
request = urllib2.Request(‘https://accounts.pixiv.net/api/login?lang=zh’,encodeData,headers)
response = opener.open(request)
request2 = urllib2.Request(‘https://www.pixiv.net/bookmark.php’)
response2 = opener.open(request2)
print response2.read()
Python中使用urllib2模拟登录pixiv遇到了问题
你没有验证登录是否成功吗? 看一下 response 或许你没有登录成功呢.
我最近也折腾过pixiv的登录,urllib2确实有点老了,现在用requests配合session会更方便。主要问题是pixiv的登录需要处理POST参数和cookie。
import requests
from bs4 import BeautifulSoup
def login_pixiv(username, password):
# 创建session保持登录状态
session = requests.Session()
# 先获取登录页面,拿到必要的token
login_url = "https://accounts.pixiv.net/login"
response = session.get(login_url)
soup = BeautifulSoup(response.text, 'html.parser')
# 查找post_key参数(pixiv的防CSRF token)
post_key = None
for input_tag in soup.find_all('input'):
if input_tag.get('name') == 'post_key':
post_key = input_tag.get('value')
break
if not post_key:
print("无法找到post_key,可能需要检查页面结构")
return None
# 构建登录数据
login_data = {
'pixiv_id': username,
'password': password,
'post_key': post_key,
'return_to': 'https://www.pixiv.net/'
}
# 发送登录请求
login_post_url = "https://accounts.pixiv.net/api/login"
headers = {
'Referer': 'https://accounts.pixiv.net/login',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
login_response = session.post(login_post_url, data=login_data, headers=headers)
# 检查是否登录成功
if login_response.status_code == 200:
# 可以尝试访问需要登录的页面验证
test_response = session.get("https://www.pixiv.net/")
if "logout" in test_response.text.lower():
print("登录成功!")
return session
else:
print("登录可能失败,请检查账号密码")
return None
else:
print(f"登录请求失败,状态码:{login_response.status_code}")
return None
# 使用示例
if __name__ == "__main__":
# 替换成你的账号密码
username = "your_email@example.com"
password = "your_password"
session = login_pixiv(username, password)
if session:
# 现在可以用这个session访问需要登录的页面
# 例如获取关注列表
following_url = "https://www.pixiv.net/ajax/following"
response = session.get(following_url)
print(response.json())
关键点:
- 用requests.Session()保持cookie
- 先从登录页面获取post_key(防CSRF token)
- 登录时需要正确的Referer和User-Agent
- 登录成功后用同一个session访问其他页面
如果遇到验证码或者登录失败,可能需要检查网络环境或者账号状态。
确实是没登录成功,但是不知道哪里出了问题,提交的表单和 header 设置的应该都是没错的,我用 requests 库进行模拟登陆都成功了,所以特别疑惑
你可以用 fiddler (Windows) 或者其他监控程序来看看你 urllib2 和 requests 发送的 HTTP 请求内容具体有什么不同.
github 上看来下 好像都是用 oauth 的
def auth(self, username=None, password=None, refresh_token=None):
“”“Login with password, or use the refresh_token to acquire a new bearer token”""
url = ‘https://oauth.secure.pixiv.net/auth/token’
headers = {
‘App-OS’: ‘ios’,
‘App-OS-Version’: ‘10.3.1’,
‘App-Version’: ‘6.7.1’,
‘User-Agent’: ‘PixivIOSApp/6.7.1 (iOS 10.3.1; iPhone8,1)’,
}
data = {
‘get_secure_url’: 1,
‘client_id’: ‘bYGKuGVw91e0NMfPGp44euvGt59s’,
‘client_secret’: ‘HP3RmkgAmEGro0gn1x9ioawQE8WMfvLXDz3ZqxpK’,
}
if (username is not None) and (password is not None):
data[‘grant_type’] = ‘password’
data[‘username’] = username
data[‘password’] = password
elif (refresh_token is not None) or (self.refresh_token is not None):
data[‘grant_type’] = ‘refresh_token’
data[‘refresh_token’] = refresh_token or self.refresh_token
else:
raise PixivError(’[ERROR] auth() but no password or refresh_token is set.’)
r = self.requests_call(‘POST’, url, headers=headers, data=data)
if (r.status_code not in [200, 301, 302]):
if data[‘grant_type’] == ‘password’:
raise PixivError(’[ERROR] auth() failed! check username and password.\nHTTP %s: %s’ % (r.status_code, r.text), header=r.headers, body=r.text)
else:
raise PixivError(’[ERROR] auth() failed! check refresh_token.\nHTTP %s: %s’ % (r.status_code, r.text), header=r.headers, body=r.text)
token = None
try:
# get access_token
token = self.parse_json(r.text)
self.access_token = token.response.access_token
self.user_id = token.response.user.id
self.refresh_token = token.response.refresh_token
except:
raise PixivError(‘Get access_token error! Response: %s’ % (token), header=r.headers, body=r.text)
# return auth/token response
return token
非常感谢你的方法,用工具抓包发现是因为 p 站在打开登陆界面会设置一个 cookie,用 requests 库发包的时候会自动把那个 cookie 带上,而 urllib2 得自己设置
Pixiv 在用户首次访问时,会设置一个 post_key 做为 CSRF 防护
并不用读取 cookies,这个 post_key 会放在响应的 body 中
你可以用 /postKey":"([a-zA-Z0-9]+)"/ 匹配得到

