Closed yuyuko-C closed 3 years ago
Pixiv在不同环境下会返回不同的结果。我写了一段类似的代码进行测试,如下:
(可以不加改动直接运行,兼容pixivpy_async)
# !/usr/bin/env python
# -*- coding: utf-8 -*-
from pixivpy_async.sync import AppPixivAPI
class TempAPI(AppPixivAPI):
def check_ck(self):
url = "https://httpbin.org/cookies"
return self.requests_('GET', url, auth=False)
def search_ajax(self, keyword:str, page:int=1, order="date_d", s_mode="s_tag_full"):
url="https://www.pixiv.net/ajax/search/illustrations/{}".format(keyword)
params={
"word":keyword,
"order":order,
"mode":"all",
"p":page,
"s_mode":s_mode,
"type":"illust_and_ugoira",
"lang":"zh",
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/63.0.3239.132 Safari/537.36',
'Referer': 'https://www.pixiv.net',
}
return self.requests_('GET', url, params=params, headers=headers, auth=False)
print(TempAPI(cookies={"PHPSESSID": "abc"}).check_ck(), "\n\n")
r = TempAPI().search_ajax("甘雨")
print([k.id for k in r.body.illust.data[:8]], "\n")
r = TempAPI(cookies={"PHPSESSID": "..."}).search_ajax("甘雨")
print([k.id for k in r.body.illust.data[:8]])
r = TempAPI(bypass=True, proxy="socks5://127.0.0.1:9011", cookies={"PHPSESSID": "..."}).search_ajax("甘雨")
print([k.id for k in r.body.illust.data[:8]])
r = TempAPI(bypass=True, cookies={"PHPSESSID": "..."}).search_ajax("甘雨")
print([k.id for k in r.body.illust.data[:8]])
r = TempAPI(proxy="socks5://127.0.0.1:9011", cookies={"PHPSESSID": "..."}).search_ajax("甘雨")
print([k.id for k in r.body.illust.data[:8]])
结果为
['93490933', '93490118', '93490062', '93489377', '93487463', '93487328', '93482209', '93480542']
['93491620', '93491551', '93490933', '93490118', '93490062', '93489377', '93487463', '93487328']
['93491620', '93491551', '93490933', '93490118', '93490062', '93489377', '93487463', '93487328']
['93491620', '93491551', '93490933', '93490118', '93490062', '93489377', '93487463', '93487328']
['93491620', '93491551', '93490933', '93490118', '93490062', '93489377', '93487463', '93487328']
代理环境为socks5,即 https://github.com/Mikubill/pixivpy-async/blob/master/socks5_server.py 后四次结果与登录状态下搜索结果一致,至少在socks代理环境下pixivpy_async的表现应该没有问题。
请问可以提供一下网络环境信息吗(如代理类型等)
感谢回答,经过测试后你的代码能正常使用,基于你的帮助我定位到了问题。 本条回复中包含三段信息:1.使用代理报错问题所在 2.搜索图片少的问题是否无法解决 3.一个可能为bug的地方
1. 你好 ,我已经定位到问题所在了。问题出在 headers 上,与网络代理类型并无关系。 因为我最开始基于 requests 制作时,不设置 headers 可以返回到所有结果,所以我误认为在 pixiv 中不设置 headers 并不影响结果。所以当在 aiohttp 出现问题时我并未意识到是 headers 所导致的。不过我依然不能理解的是:同样是使用代理,为何在 requests 上 与 aiohttp 会产生差别。
2. “Pixiv在不同环境下会返回不同的结果。”—— 这句话是指在 ios 环境下 pixiv 只能返回那些图片信息吗?也就是,搜索图片过少的问题是无法解决的?
3. 我将代码复制运行后发现编译器给出了错误信息
Traceback (most recent call last):
File "e:/Python_Project/Github/pypixiv/test.py", line 53, in <module>
print([k.id for k in r.body.illust.data[:8]])
AttributeError: 'str' object has no attribute 'body'
经过测试后发现,这个问题出现在 utils.py 文件的 paser_json 方法中,通过在 TempAPI 类中重写方法后即可正常使用,已经确认过了 Github 中依然是原代码,也许是你本地已经修复了但未同步到仓库,所以这代码在你的电脑中无需修改即可使用。 原代码:
@staticmethod
def parse_json(_):
return json.loads(json.dumps(_), object_hook=JsonDict)
修改后:
def parse_json(self,value:str):
return json.loads(value, object_hook=JsonDict)
PixivIOSApp/7.6.2 (iOS 12.2; iPhone9,1)
的Header。request和aiohttp会出现不同结果,应该是因为这个导致的服务器返回结果不一致吧json.dumps
。应该没有需要处理str
的情况...
https://github.com/Mikubill/pixivpy-async/blob/958783cca3204f99cf7efc698176acb988bc36c0/pixivpy_async/net.py#L581.我之前没有考虑到这个,但经测试后发现在设置的 PHPSESSIDE 后发送请求时,如果 User-Agent 为空或不存在的 UA 以及 PixivIOSApp/7.6.2 (iOS 12.2; iPhone9,1)
时,返回的确会出现问题。我是基于 Net 类制作的,并未使用 Utils 类中的 set_headers 函数,所以导致我出问题是因为 headers 为空。
2.搜索数量过少是通过遍历得到的。也就是一直到 next_url
为空为止的统计数量,不过这个 API 有 offset
的限制,不能大于5000。经过我的大量测试,返回数量是由P站不同客户端的机制不同导致的,不过我也没摸清机制。可能是我运气好,选择了"搜索"恶毒。在浏览器和 pixiv_async
搜索 “恶毒” 返回的数量差异及其大,网站上返回数量为2,027,pixiv_async 返回数量为219,所以我发现了这个问题。
3.这个bug是我在调试返回结果的时候改动了源代码导致的。因为错误结果无法使用 res.json()
,我临时改为 res.text()
没有改回来。
框架不存在问题,打扰到你了不好意思。
就搜索数量差异的问题,我在pixiv上搜索“恶毒”(简体,中文)时网页API返回结果数量也是219,不过如果用ル・マラン(日语)来搜索网页API的返回数量就和你描述的比较接近了(~2010)。同时aapi也有类似的结果。
有可能是pixiv的网页API在部分时候会合并同类词搜索结果)
我在两端搜索ル・マラン(日语)返回的结果数量是一模一样的,差别就是在搜索“恶毒”(简体,中文)的时候。不过有个意外的发现:如果搜索的是“恶毒”(简体,中文),那排除掉的都是tags不存在“恶毒”(简体,中文)的画作。如果将网页端的搜索规则改为:tags 完全一致,数量则和pixivpy_sync
中tags部分一致的数量特别相近,但也不是完全相同。
这问题也是头大)
感谢恋恋的耐心解答,这 Issue 尴尬地想删了 orz。
不知道应不应该反馈到这里,如果打扰了还请见谅。 因为本项目中的搜索结果的数量很明显少于实际值,我自己基于本项目中的网络请求做了一套浏览器的P站爬虫,因为需要设置cookie来绕过登录,在使用中就发现了如题所述的问题。
设置的cookie是P站返回的 PHPSSEID 。以下是我使用的一些记录。
测试: 1.使用 requests 的 proxies 后设置 cookies ,成功返回P站在已登录情况下的结果。 2.使用 pixivpy-async 的 proxies 后不设置 cookies,成功返回P站在未登录情况下的结果 3.使用 pixivpy-async 的 proxies 后设置 cookies,报错(返回403)。 4.使用 pixivpy-async 的 bypass 后设置 cookies,成功返回P站在已登录情况下的结果。
测试代码如下:
本人推测是因为使用了 ProxyConnector 导致的报错,如果 TCPConnector 会不会报错尚不可知,因为不使用代理的情况下无法访问P站。如果能回答我的话将不胜感激。