p站收藏夹爬虫

使用须知:访问p站需要梯子,请自行准备,推荐方法(需要安装ca证书,请自行取舍)

pixiv在很多地方都要验证登入,所以必须使用cookie来保持通话

先放码

import requests
import json
import os
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

#从本地读取保存下的cookies进行解析(建议使用[edit this cookie]浏览器程序),也可以从请求头中获取。
def cookies_load():
	cookies_json = {}
	try:
		cookies = json.load(open('cookies.json','r',encoding = 'utf-8'))
	except:
		print('cookies读取失败')
	else:
		for cook in cookies:
			if cook['domain'] == '.pixiv.net':
				cookies_json[cook['name']] = cook['value']
		return cookies_json


def get_session():
	head = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400',
	'Accept-Language': 'zh-CN,zh;q=0.9',
	'Accept-Encoding': '',
	'Referer': 'https://www.pixiv.net/',
	}

	cookies_json = cookies_load()       #若是从请求头中获取cookie的,就不用使用cookies_load方法

	session = requests.session()
	session.headers = head
	requests.utils.add_dict_to_cookiejar(session.cookies,cookies_json)

	return session


def get_collection(page):
	session = get_session()
	collection_url = 'https://www.pixiv.net/ajax/user/{}/illusts/bookmarks?tag=&offset={}&limit=48&rest=show'.format(id,page*48) #将id改为你的账户uid
	try:
		collection_data = session.get(collection_url,timeout = 20,verify = False).json()
	except:
		print('收藏夹第{}页获取失败'.format(page+1))
		return False
	else:
		print('请求第{}页成功'.format(page+1))
		return collection_data


def get_img_url():
	img_url_list = []
	session = get_session()
	for page in range(1000):
		collection_data = get_collection(page)
		if collection_data == False:
			pass
		else:
			total = collection_data['body']['total']
			works = collection_data['body']['works']
			for img_item_data in works:
				img_item_url = 'https://www.pixiv.net/ajax/illust/'+img_item_data['id']+'/pages'     #图片的异步请求url
				try:
					img_item = session.get(img_item_url,verify = False).json()
				except:
					print('图片获取失败:'+img_item_data['id'])
				else:
					for img_data in img_item['body']:
						img_url = img_data['urls']['original']    #无损画质的图片地址,直接访问会403
						img_url_list.append(img_url)
				if (page+1)*48 > total:
					return img_url_list


def folder_mkdir():
	if os.path.exists(os.getcwd()+'\\pixiv'):
		pass
	else:
		os.mkdir(os.getcwd()+'\\pixiv')

	img_folder = os.getcwd()+'\\pixiv'        #可以自行修改成你需要的存储位置
	return img_folder


def install_img():
	head = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400',
	'Accept-Language': 'zh-CN,zh;q=0.9',
	'Accept-Encoding': '',
	'Referer': 'https://www.pixiv.net/',
	}
	img_folder = folder_mkdir()
	session = get_session()
	img_url_list = get_img_url()
	json.dump(img_url_list,open('url.txt','w'))
	erro_url = []
	n = 0
	for img_url in img_url_list:
		try:
			img_content = session.get(img_url,timeout = 30,verify = False).content
		except:
			print('请求失败:'+img_url)
		else:
			n += 1
			open(img_folder+'\\'+str(n)+img_url[-4:],'wb').write(img_content)
			if n % 10 == 0:
				print('已保存{}张'.format(n))


def main():
	install_img()

if __name__ == '__main__':
	main()

cookies_load()

import json
def cookies_load():
	cookies_json = {}
	try:
		cookies = json.load(open('cookies.json','r',encoding = 'utf-8'))  #使用load方法将文件中的json格式的资料读取出来
	except:
		print('cookies读取失败')
	else:
		for cook in cookies:
			if cook['domain'] == '.pixiv.net':
				cookies_json[cook['name']] = cook['value']
		return cookies_json

我定义的第一个方法是cookies_load,这个看名字就知道是关于cookie的。这里推荐使用浏览器开发工具edit this cookie。可以快速的将cookie保存成json格式,不过不使用了也不碍事。

我们先开启F12,登入pixiv后,在Network里的XHR选项卡中查看请求的请求头,里面键名为Cookie的值就死我们需要的cookie。

p站收藏夹爬虫_第1张图片p站收藏夹爬虫_第2张图片
第一张是直接从请求头中获取cookie的方法,第二种是使用edit this cookie获取cookie的方法。

get_session()

import requests
def get_session():   #注:默认参数要放在指定参数前
	head = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400',
	'Accept-Language': 'zh-CN,zh;q=0.9',
	'Accept-Encoding': '',
	'Referer': 'https://www.pixiv.net/',
	}

	cookies_json = cookies_load()

	session = requests.session()
	session.headers = head
	requests.utils.add_dict_to_cookiejar(session.cookies,cookies_json)

	return session

配置请求,添加cookie等验证信息,方便后面引用。

get_collection()

from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
def get_collection(page):
	session = get_session()
	collection_url = 'https://www.pixiv.net/ajax/user/{}/illusts/bookmarks?tag=&offset={}&limit=48&rest=show'.format(50465050,page*48) #将id改为你的账户uid
	try:
		collection_data = session.get(collection_url,timeout = 20,verify = False).json()
	except:
		print('收藏夹第{}页获取失败'.format(page+1))
		return False
	else:
		print('请求第{}页成功'.format(page+1))
		return collection_data

首句先获取已经配置好的session来用于后续的请求
p站收藏夹爬虫_第3张图片
p站收藏夹爬虫_第4张图片
被我抹掉的是uid,在配置的时候请自行添加。收藏夹每一页会加载48个图片项目。所以要获取第二页内容只要将limit的值*2,改为96就可以了。
相信大家已经注意到了开头的那个库引用,已经请求时添加的参数verify,这是由于我安装的证书不被信任导致的,添加verify=False关闭检测证书。在引用库关闭警告。

from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

get_img_url()

def get_img_url():
	img_url_list = []
	session = get_session()
	for page in range(1000):
		collection_data = get_collection(page)
		if collection_data == False:
			pass
		else:
			total = collection_data['body']['total']
			works = collection_data['body']['works']
			for img_item_data in works:
				img_item_url = 'https://www.pixiv.net/ajax/illust/'+img_item_data['id']+'/pages'     #图片的异步请求url
				try:
					img_item = session.get(img_item_url,verify = False).json()
				except:
					print('图片获取失败:'+img_item_data['id'])
				else:
					for img_data in img_item['body']:
						img_url = img_data['urls']['original']    #无损画质的图片地址,直接访问会403
						img_url_list.append(img_url)
				if (page+1)*48 > total:
					return img_url_list

由于我们并不知道收藏夹有多少页的内容,所以设置尽可能多的页数range(1000),后续有验证最后一页的方法。
我们先看请求出的json格式的收藏夹数据
p站收藏夹爬虫_第5张图片
可以看到图片项目数据储存的关系是[data[body[works]]]。而且在works上方也标出了总收参数,已知一页有48个项目,这样就可以作为判断标准了。

if (page+1)*48 > total:
	return img_url_list

folder_mkdir()

import os
def folder_mkdir():
	if os.path.exists(os.getcwd()+'\\pixiv'):
		pass
	else:
		os.mkdir(os.getcwd()+'\\pixiv')

	img_folder = os.getcwd()+'\\pixiv'        #可以自行修改成你需要的存储位置
	return img_folder

这个就不需要多说了吧,在运行目录下创建一个文件夹,传出文件地址。

install_img()

def install_img():
	head = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400',
	'Accept-Language': 'zh-CN,zh;q=0.9',
	'Accept-Encoding': '',
	'Referer': 'https://www.pixiv.net/',
	}
	img_folder = folder_mkdir()
	session = get_session()
	img_url_list = get_img_url()
	json.dump(img_url_list,open('url.txt','w'))
	erro_url = []
	n = 0
	for img_url in img_url_list:
		try:
			img_content = session.get(img_url,timeout = 30,verify = False).content
		except:
			print('请求失败:'+img_url)
		else:
			n += 1
			open(img_folder+'\\'+str(n)+img_url[-4:],'wb').write(img_content)
			if n % 10 == 0:
				print('已保存{}张'.format(n))

顾名思义这个函数使用于下载已获取的图片url中的图片。
这里其实可以再改下,防止重复下载相同的内容,但是我这里懒的弄了。可以在

json.dump(img_url_list,open(‘url.txt’,‘w’))

这个位置下点功夫,若图片地址重复,则退出

差不多就到这了,main()函数入口,为了好看。

时间:2020/3/29

你可能感兴趣的:(爬虫,python)