1 Commits

Author SHA1 Message Date
lamp e9f2a5606a delete junk
i branched
2021-09-24 10:53:14 -07:00
4 changed files with 48 additions and 134 deletions
+2 -1
View File
@@ -1 +1,2 @@
.env PHPSESSID.txt
download
+11
View File
@@ -0,0 +1,11 @@
This is a python script for downloading original pixiv images from popular search results via a premium account.
# Instructions
1. Download this repo to your computer of course, and open the terminal in it. Run `pip install -r requirements.txt` if necessary.
2. In your browser, on Pixiv logged in to a premium account, in dev tools Application tab, copy the **value** of the `PHPSESSID` cookie, and paste it into a new file named `PHPSESSID.txt` in this folder.
3. Run `python pixiv-popular-downloader.py -h` for usage information. Example usage to download 10 pages of 初音ミク tag, including r18: `python pixiv-popular-downloader.py -r -p 10 "初音ミク"`
4. Check the download folder. If you're getting newest results instead of popular results, then your PHPSESSID failed to work.
+33 -129
View File
@@ -3,145 +3,49 @@ import requests
from requests_toolbelt.adapters import host_header_ssl from requests_toolbelt.adapters import host_header_ssl
from urllib.parse import quote as encodeURI from urllib.parse import quote as encodeURI
import os import os
from pymongo import MongoClient
from gridfs import GridFS
from datetime import datetime
from dotenv import load_dotenv
load_dotenv()
ap = argparse.ArgumentParser() ap = argparse.ArgumentParser()
ap.add_argument("tag", help="Pixiv tag(s) to search") ap.add_argument("tag", help="Pixiv tag(s) to search")
ap.add_argument("-p", dest="numpages", type=int, default=1, help="number of pages to download (default 1)") ap.add_argument("-p", dest="numpages", type=int, default=1, help="number of pages to download (default 1)")
ap.add_argument("-s", dest="startpagenum", type=int, default=1, help="page number to start at") ap.add_argument("-s", dest="startpagenum", type=int, default=1, help="page number to start at")
ap.add_argument("-r", action='store_true', help="include r18 posts")
args = ap.parse_args() args = ap.parse_args()
PHPSESSID = None
with open("PHPSESSID.txt", 'r') as f:
PHPSESSID = f.read()
rqs = requests.Session() rqs = requests.Session()
rqs.mount('https://', host_header_ssl.HostHeaderSSLAdapter()) rqs.mount('https://', host_header_ssl.HostHeaderSSLAdapter())
download_count = 1
for i in range(args.startpagenum, args.numpages+1):
dbclient = MongoClient(os.environ["MONGODB_URI"]) page_url = f"https://210.140.131.219/ajax/search/artworks/{encodeURI(args.tag, safe='')}?order=popular_d&mode={'all' if args.r else 'safe'}&p={i}"
print("get", page_url)
db = dbclient["mikudb"] page_data = rqs.get(page_url, cookies={"PHPSESSID": PHPSESSID}, headers={"host":"www.pixiv.net"}).json()
illustration_collection = db["illustration_collection"] if (page_data['error']):
search_collection = db["search_collection"] print(page_data['message'])
gridfs = GridFS(db)
def download_popular(tag, startpagenum = 1, numpages = 1):
# record this search session in the database
search_document_id = search_collection.insert_one({
"date": datetime.now(), # date started
"query": None, # the tag being searched
"current_page": startpagenum, # keep track of the page we're on
"current_illust": None, # keep track of which item is being downloaded
"search_data": [], # save each payload
"results": [], # collect ids of all results that were saved
"completed": False # whether this ever reached the end
}).inserted_id
the_id_of_the_first_result_on_the_previous_page = None
for page_number in range(startpagenum, numpages+1):
# download search results
search_url = f"https://210.140.131.219/ajax/search/artworks/{encodeURI(tag, safe='')}?order=popular_d&mode=all&p={page_number}"
print("get", search_url)
search_data = rqs.get(search_url, cookies={"PHPSESSID": os.environ["PHPSESSID"]}, headers={"host":"www.pixiv.net"}).json()
# save raw search data
search_collection.update_one({"_id": search_document_id}, {"$set": {"current_page": page_number}, "$push": {"search_data": {
"page_number": page_number,
"search_url": search_url,
"search_data": search_data
}}})
if (search_data['error']):
print("error from search api:", search_data['message'])
exit(1) exit(1)
for illust in page_data['body']['illustManga']['data']:
search_results = search_data['body']['illustManga']['data'] illust_r18 = bool(illust['xRestrict'])
illust_url = f"https://210.140.131.219/ajax/illust/{illust['id']}/pages"
# if there is no data then we are done print("get", illust_url)
if not search_results: illust_data = rqs.get(illust_url, headers={"host":"www.pixiv.net"}).json()
print("No more search results") if (illust_data['error']):
search_collection.update_one({"_id": search_document_id}, {"$set":{"completed": True}}) print(illust_data['message'])
exit()
# But large tags seem to give the last page of results for any page number
if search_results[0]['id'] == the_id_of_the_first_result_on_the_previous_page:
print("Reached duplicate search results, looks like the end")
search_collection.update_one({"_id": search_document_id}, {"$set":{"completed": True}})
exit()
else: the_id_of_the_first_result_on_the_previous_page = search_results[0]['id']
# for each search result
for illust_data_from_search in search_results:
illust_id = illust_data_from_search['id']
search_collection.update_one({"_id": search_document_id}, {"$set":{"current_illust": illust_id}})
# check if this illust was already saved
if illustration_collection.count_documents({"_id": illust_id}):
print("already have", illust_id)
continue
# illust_metadata_from_search has limited information (blank descriptions)
# download full meta data from ajax
illust_ajax_url = f"https://210.140.131.219/ajax/illust/{illust_id}"
print("get", illust_ajax_url)
illust_ajax_data = rqs.get(illust_ajax_url, cookies={"PHPSESSID": os.environ["PHPSESSID"]}, headers={"host":"www.pixiv.net"}).json()
if (illust_ajax_data['error']):
print("error from ajax api:", illust_ajax_data['message'])
# illust_ajax_data does not have "page" data (additional image urls)
# download that
illust_pages_url = illust_ajax_url + "/pages"
print("get", illust_pages_url)
illust_pages_data = rqs.get(illust_pages_url, cookies={"PHPSESSID": os.environ["PHPSESSID"]}, headers={"host":"www.pixiv.net"}).json()
if (illust_pages_data['error']):
print("error from ajax pages api:", illust_pages_data['message'])
else: else:
for image in illust_data['body']:
# prepare database document image_url = image['urls']['original']
document = { download_dir = f"download/{args.tag}/"
"_id": illust_id, # use the unique artwork id for document id so we can't have duplicates os.makedirs(download_dir, exist_ok=True)
"illust_ajax_data": illust_ajax_data, # save all the metadata for the artwork download_filename = str(download_count) + '_' + ('x_' if illust_r18 else '') + image_url.split('/').pop()
"illist_pages_data": illust_pages_data, # save all the image urls of the data download_path = download_dir + download_filename
"downloaded_images": {}, # map of image filenames to gridfs ids if os.path.exists(download_path):
"date_saved": datetime.now() print(download_path, "already exists")
} continue
print("get", image_url)
# download originals res = rqs.get(image_url, headers={'referer':'https://www.pixiv.net'})
for illust_page_data in illust_pages_data['body']: with open(download_path, "wb") as f:
f.write(res.content)
original_image_url = illust_page_data['urls']['original'] print("saved", download_filename)
original_image_filename = original_image_url.split('/').pop() download_count = download_count + 1
print("get", original_image_url)
res = rqs.get(original_image_url, headers={'referer':'https://www.pixiv.net'})
print("gridfs put", res.url)
gridfs_id = gridfs.put(res.content)
document['downloaded_images'][original_image_filename] = gridfs_id
# add to db
illustration_collection.insert_one(document)
search_collection.update_one({"_id": search_document_id}, {"$push": {"results":{
"id": illust_id
}}})
search_collection.update_one({"_id": search_document_id}, {"$set":{"completed": True}})
print("end of loop")
download_popular(args.tag, args.startpagenum, args.numpages)
-2
View File
@@ -1,5 +1,3 @@
requests==2.26.0 requests==2.26.0
requests-toolbelt==0.9.1 requests-toolbelt==0.9.1
urllib3==1.26.6 urllib3==1.26.6
pymongo==3.12.0
python-dotenv==0.19.0