hello呀,小伙伴们,今个给大家带来的是爬取P站的教程,别搞错,这个不是你想的那个p站。这样想肯定是你用黄黄的思想点进来的。众所周知,P站是个插画网站,也包含一些R18的插画。停停停!!!突然打脸了...
我说的是Pixiv这个网站,哎,真的不一样啊。这是只有插画没有视频的P站哦。搞错的同学可以不要看下去了~仅给有需要它的人观看~
Pixiv,是一个主要由日本艺术家所组成的虚拟社群,主体为由pixiv股份制有限公司所运营的为插画艺术特化的社交网络服务网站。新兴的日本同人画、插画作品分享站点。So,今天我们就拿他开刀了…
老套路,让我们首先输入网址:
然后可以看到地址栏的网址链接直接变成:
https://pixivic.com/?VNK=28072886,
当然有的小伙伴的想法可能是上来就去获取元素标签,然后一通操作猛如虎,结果傻成二百五,碰到这种事,还是需要先看看网站的数据是怎么来的,F12审查元素,然后一直下拉获取数据,可以看出页面的数据是动态加载出来的。如图:
我们拿到请求的API地址后,先分析下数据,
https://api.pixivic.com/ranks?page=1&date=2020-06-11&mode=day&pageSize=30,
直接在浏览器中输入,然后找个 json美化工具,可以看出具体返回数据有哪些,通过和原网页进行比对可以得出如下结果:
我们的目的就是为了拿到图片地址,然后下载图片,所以我们复制图片地址查看图片能否正常预览,结果我们发现:
由此可以得出,该网站做了反爬措施,那该怎么办呢,首先让我们分析下:
页面正常打开没进行任何登陆操作,所以不存在时cookie这种问题,所以我们看下是不是请求头的原因,经分析和测试后发现,是需要添加refer,故在请求头中加入即可正常访问。如图:
接下来,就进入敲代码的环节,如下:
import requests # 导入requests库
import re # 导入正则表达式库
import os # 保存文件
import threading # 导入多线程库
os.system('title pixiv排行榜爬取') # 设置窗口标题
if not os.path.exists('pixivimg'): # 判断文件夹是否存在,如果不存在:
os.mkdir('pixivimg') # 创建一个文件夹
print('原网站:[url=https://pixivic.com/]https://pixivic.com/[/url],如无法爬取请尝试访问获取VNK')
print('因本人只看插画,所以为名字与插画对应,实际上获得的图片少于原页面上应有的图片。')
VNK = input('请输入VNK(可跳过):') # 获取VNK,虽然仍然不知道有什么用,不过是根据ua变化的VNK
if VNK == '':
VNK = 'dbcbfa01' # 默认的VNK
data = input('请输入爬取的日期(例如2020-06-12,最近的数据为三天前数据!):') # 获取爬取日期
pages = int(input('你想爬取的页数(1~18),每页大概30张图片:')) # 因为异步加载,所以实际上是多页
# 爬取单页的函数
def get_pixiv(page):
user = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
} # 这里的ua随便写写就好,无限制
url = 'https://api.pixivic.com/ranks?page=' + str(
page) + '&date=' + data + '&mode=day&pageSize=30' # 异步加载接口,返回json数组
response = requests.get(url, headers=user) # 模拟访问
response.encoding = response.apparent_encoding # 防止乱码
html = response.text # 用文本显示访问网页得到的内容
urls = re.findall('"original":"https://i.pximg.net/img-original/img/(..../../../../../../[0-9]*?_p0.*?g)"',
html) # 用正则表达式获得本页各网址
names = re.findall('"artistId":.*?,"title":"(.*?)","type"', html) # 获取图片名字
ids = re.findall('"original":"https://i.pximg.net/img-original/img/..../../../../../../([0-9]*?)_p0.*?g"',
html) # 获取图片id,为后面referer做准备
for name, url, id in zip(names, urls, ids):
user = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362',
'Referer': 'https://pixivic.com/illusts/' + id + '?VNK=' + VNK, # 缺少此将返回403
'Accept': 'image/png, image/svg+xml, image/*; q=0.8, */*; q=0.5',
'Host': 'original.img.cheerfun.dev',
'Cache-Control': 'max-age=0',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'Keep-Alive',
'Accept-Language': 'zh-CN'
}
url = 'https://original.img.cheerfun.dev/img-original/img/' + url # 真实的原图地址,抓包获得,无法直接访问
try:
name = name.replace('\\', '_') # 防止创建文件时因名字问题失败
name = name.replace('?', '过滤')
except:
name = name
response = requests.get(url, headers=user) # 模拟访问
if response.status_code == 200: # 200即为成功
print('正在下载图片:' + name)
else:
print('错误代码' + response.status_code + '下载图片' + name + '失败!')
with open('pixivimg' + '/' + name + '.jpg', 'wb') as f: # 保存图片
f.write(response.content)
for page in [x for x in range(1, pages + 1)]: # 生成数字列表,便于循环爬取
threading.Thread(target=get_pixiv, args=(page,)).start() # 启动多线程
右击运行代码,输入你的想要爬取得内容,看到下图即代表程序执行成功