一个简单的p站作者查询脚本

使用这部分请保证网络条件允许访问相关网站

本脚本仅供学习使用,也为本人学习练习使用,如违规使用导致涉及ip封禁,或者触犯法律和本人无关

找到该脚本的源码可以->点这里

一、脚本功能

  • 支持通过一个完整的pid来进行快速访问
  • 支持通过一个完整的pid来进行对该pid对应作者的作品悉数爬取
  • 爬取的作品会创建一个文件夹进行保存

二、编写过程

1、环境配置

本脚本已经内置环境下载部分,但是请准备python环境

手动部署环境如下

在脚本文件内打开终端完成,键入以下来完成环境配置

1
2
pip install selenium
pip install requests

2、导入必要的库

在脚本的开头,导入所需的库:

1
2
3
4
5
6
7
import os
import time
import random
import subprocess
import sys
from tkinter import *
from tkinter import font

3、检查并安装库

编写一个函数来检查并安装缺失的库:

1. 安装库的函数

1
2
def install(package):
subprocess.check_call([sys.executable, "-m", "pip", "install", package])

定义一个名为 install 的函数,用于安装指定的 Python 包。

subprocess.check_call(...):这个函数用于在 Python 中调用外部命令。在这里,它调用 pip 来安装指定的包。

sys.executable:返回当前 Python 解释器的路径,确保在正确的 Python 环境中执行安装命令。

"-m", "pip", "install", package:这是传递给 Python 的参数,表示使用 pip 模块来安装指定的包

2. 尝试导入 requests 库

1
2
3
4
try:
import requests
except ImportError:
install('requests')

尝试导入 requests 库,这是一个用于发送 HTTP 请求的流行库。

try 块:尝试执行 import requests

except ImportError:如果 requests 库未安装,Python 会抛出 ImportError 异常,进入 except 块。

install('requests'):调用之前定义的 install 函数,安装 requests 库。

3. 尝试导入 selenium 库及其组件

1
2
3
4
5
6
7
try:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.microsoft import EdgeChromiumDriverManager
except ImportError:
install('selenium')

尝试导入 selenium 库及其相关组件,这些组件用于自动化浏览器操作。

try 块:尝试导入 selenium 的多个模块:
from selenium import webdriver:导入 webdriver,用于控制浏览器。

from selenium.webdriver.common.by import By:导入 By 类,用于定位网页元素。

from selenium.webdriver.chrome.service import Service:导入 Service 类,用于管理 ChromeDriver 的服务。

from webdriver_manager.microsoft import EdgeChromiumDriverManager:导入 EdgeChromiumDriverManager,用于自动下载和管理 Microsoft EdgeWebDriver

except ImportError:如果 selenium 库未安装,Python 会抛出 ImportError 异常,进入 except 块。

install(‘selenium’):调用之前定义的 install 函数,安装 selenium 库。

4、函数jump_to_author

1
2
3
4
5
def jump_to_author():
uid = uid_entry.get()
driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()))
author_url = "https://www.pixiv.net/users/" + uid
driver.get(author_url)
  1. 获取用户输入的 UID

    1
    uid = uid_entry.get()
    • 从 Tkinter 界面的输入框中获取用户输入的 UID(用户 ID),并将其存储在变量 uid 中。
  2. 初始化 WebDriver

    1
    driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()))
    • 使用 webdriver_manager 自动下载和管理 Microsoft Edge 的 WebDriver。
    • 创建一个 webdriver.Edge 实例,允许脚本控制 Edge 浏览器。
  3. 构建用户页面 URL

    1
    author_url = "https://www.pixiv.net/users/" + uid
    • 根据用户输入的 UID 构建 Pixiv 用户页面的 URL。
  4. 打开用户页面

    1
    driver.get(author_url)
    • 使用 WebDriver 打开构建的用户页面 URL。

5、函数 download_all_works

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def download_all_works():
uid = uid_entry.get()
author_url = "https://www.pixiv.net/users/" + uid

driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()))
driver.get(author_url)

driver.implicitly_wait(10)
works = driver.find_elements(By.CSS_SELECTOR, "a[href*='/artworks/']")
work_links = [work.get_attribute('href') for work in works]

os.makedirs(uid, exist_ok=True)

max_requests = 100
request_count = 0

for link in work_links:
if request_count >= max_requests:
print("达到最大请求次数,暂停一段时间...")
time.sleep(3600)
request_count = 0

try:
driver.get(link)
time.sleep(random.uniform(2, 5))

img_element = driver.find_element(By.CSS_SELECTOR, "img[src*='img-master']")
img_url = img_element.get_attribute('src')

img_data = requests.get(img_url).content
img_name = os.path.join(uid, img_url.split('/')[-1])

with open(img_name, 'wb') as handler:
handler.write(img_data)

request_count += 1

except Exception as e:
print(f"请求失败: {e}")
time.sleep(10)

driver.quit()
print("所有作品已下载。")
  1. 获取用户输入的 UID

    1
    uid = uid_entry.get()
    • 从 Tkinter 界面的输入框中获取用户输入的 UID。
  2. 构建用户页面 URL

    1
    author_url = "https://www.pixiv.net/users/" + uid
    • 根据用户输入的 UID 构建 Pixiv 用户页面的 URL。
  3. 初始化 WebDriver

    1
    2
    driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()))
    driver.get(author_url)
    • 创建一个 webdriver.Edge 实例,并打开用户页面。
  4. 隐式等待

    1
    driver.implicitly_wait(10)
    • 设置隐式等待时间为 10 秒,确保在查找元素时,如果元素未立即出现,WebDriver 会等待最多 10 秒。
  5. 查找作品链接

    1
    2
    works = driver.find_elements(By.CSS_SELECTOR, "a[href*='/artworks/']")
    work_links = [work.get_attribute('href') for work in works]
    • 使用 CSS 选择器查找所有包含 /artworks/ 的链接,表示该用户的作品。
    • 将找到的链接存储在 work_links 列表中。
  6. 创建用户目录

    1
    os.makedirs(uid, exist_ok=True)
    • 创建一个以 UID 命名的目录,用于存储下载的作品。如果目录已存在,则不会引发错误。
  7. 设置请求限制

    1
    2
    max_requests = 100
    request_count = 0
    • 设置最大请求次数为 100 次,防止过于频繁的请求导致被封禁。
  8. 循环下载作品

    1
    for link in work_links:
    • 遍历每个作品链接,进行下载。
  9. 请求次数检查

    1
    2
    3
    4
    if request_count >= max_requests:
    print("达到最大请求次数,暂停一段时间...")
    time.sleep(3600)
    request_count = 0
    • 如果请求次数达到最大值,暂停 1 小时,然后重置请求计数。
  10. 下载作品

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    try:
    driver.get(link)
    time.sleep(random.uniform(2, 5))

    img_element = driver.find_element(By.CSS_SELECTOR, "img[src*='img-master']")
    img_url = img_element.get_attribute('src')

    img_data = requests.get(img_url).content
    img_name = os.path.join(uid, img_url.split('/')[-1])

    with open(img_name, 'wb') as handler:
    handler.write(img_data)

    request_count += 1
    • 使用 try 块来处理可能出现的异常。
    • 打开作品链接,随机等待 2 到 5 秒,以模拟人类行为,避免被检测为机器人。
    • 查找作品的图片元素,获取其 URL。
    • 使用 requests 库下载图片数据。
    • 将图片保存到之前创建的目录中,文件名为图片 URL 的最后一部分。
    • 增加请求计数。
  11. 异常处理

    1
    2
    3
    except Exception as e:
    print(f"请求失败: {e}")
    time.sleep(10)
    • 如果在下载过程中发生任何异常,打印错误信息并等待 10 秒后继续。
  12. 关闭 WebDriver

    1
    2
    driver.quit()
    print("所有作品已下载。")
    • 下载完成后,关闭 WebDriver,释放资源。
    • 打印下载完成的消息。

这两个函数的主要功能是:

  • jump_to_author:根据用户输入的 UID 跳转到该用户的 Pixiv 页面。
  • download_all_works:下载该用户的所有作品,并将其保存到本地目录中。

通过使用 Selenium 自动化浏览器操作和 Requests 下载图片,这个脚本实现了对 Pixiv 用户作品的快速访问和下载。

6、Tkinter 界面代码

1
2
3
4
window = Tk()
window.title("Pixiv作者查询")
window.geometry("400x400")
window.configure(bg="#f0f0f0")
  1. 创建主窗口
    • window = Tk():初始化 Tkinter 主窗口。
    • window.title("Pixiv作者查询"):设置窗口标题为 “Pixiv作者查询”。
    • window.geometry("400x400"):设置窗口大小为 400x400 像素。
    • window.configure(bg="#f0f0f0"):设置窗口背景颜色为浅灰色。
1
2
3
# 设置字体
title_font = font.Font(family="Helvetica", size=16, weight="bold")
label_font = font.Font(family="Helvetica", size=12)
  1. 设置字体
    • 使用 font.Font 创建字体对象,定义标题和标签的字体样式。
1
2
3
# 创建一个Frame用于组织控件
frame = Frame(window, bg="#f0f0f0")
frame.pack(pady=20)
  1. 创建 Frame
    • frame = Frame(window, bg="#f0f0f0"):创建一个 Frame 组件,用于组织其他控件。
    • frame.pack(pady=20):将 Frame 添加到主窗口,并设置上下边距为 20 像素。
1
2
3
4
5
# 创建标签和输入框
uid_label = Label(frame, text="请输入UID:", bg="#f0f0f0", font=label_font)
uid_label.pack(pady=5)
uid_entry = Entry(frame, width=30, font=label_font)
uid_entry.pack(pady=5)
  1. 创建标签和输入框
    • uid_label:创建一个标签,提示用户输入 UID。
    • uid_entry:创建一个输入框,用户可以在其中输入 UID。
    • 使用 pack() 方法将标签和输入框添加到 Frame 中,并设置上下边距。
1
2
3
4
5
6
# 创建按钮
jump_button = Button(frame, text="跳转到作者界面", command=jump_to_author, bg="#4CAF50", fg="white", font=label_font)
jump_button.pack(pady=10)

download_button = Button(frame, text="下载作者所有作品", command=download_all_works, bg="#2196F3", fg="white", font=label_font)
download_button.pack(pady=10)
  1. 创建按钮
    • jump_button:创建一个按钮,点击后调用 jump_to_author 函数,背景色为绿色。
    • download_button:创建一个按钮,点击后调用 download_all_works 函数,背景色为蓝色。
    • 使用 pack() 方法将按钮添加到 Frame 中,并设置上下边距。
1
2
3
4
5
6
7
8
9
10
11
12
# 添加提示语到窗口底部
info_frame = Frame(window, bg="#f0f0f0")
info_frame.pack(side=BOTTOM, pady=20)

info_label = Label(info_frame, text="在运行后请等待片刻,请勿关闭脚本", bg="#f0f0f0", font=label_font)
info_label.pack(pady=2)

info_label2 = Label(info_frame, text="请保证您的网络可以正常访问pixiv", bg="#f0f0f0", font=label_font)
info_label2.pack(pady=2)

info_label3 = Label(info_frame, text="仅供学习交流使用,禁止用于违法用途", bg="#f0f0f0", font=label_font)
info_label3.pack(pady=2)
  1. 添加提示信息
    • 创建一个新的 Frame info_frame,用于放置提示信息。
    • 创建多个标签 info_labelinfo_label2info_label3,分别提供运行提示、网络要求和使用声明。
    • 使用 pack() 方法将这些标签添加到 info_frame 中,并设置上下边距。
1
2
# 运行Tkinter窗口的主循环
window.mainloop()
  1. 启动主循环
    • window.mainloop():启动 Tkinter 的事件循环,等待用户操作。

该代码创建了一个简单的 Tkinter 界面,允许用户输入 Pixiv UID,并提供两个按钮以跳转到作者界面或下载作者的所有作品。

三、测试和调试

调试完打包运行即可