东风谷早苗图库搭建记录

我是一个苗厨,虽然不是早苗单推人, 但是对早苗的兴趣是认识的一位单推人带起来的(笑)
平时有收集图片的习惯,感觉Pixiv等图片网站对单角色的图片收集不是很友好,于是就打算自己写一个图库了()
苯人高二牲(快升高三了啊啊啊),平时也没什么时间写代码,所以一般在放假的时候更新。

一、爬虫部分

爬虫已经基本写完了,主要分为两个部分,爬图片的代码和更新元数据的代码,目前爬了所有Pixiv上的早苗图片。
由于对Python极其熟悉(浙江技术选考生),而且Python的爬虫库非常好用,于是全部用Python写了。

1.获取Pixiv图片id

首先准备好你的headerscookies,不然只能获取前10页的页面,而且下载也会有限制。
重点是获取Cookie中的PHPSESSID,这是你的登录凭据,登陆后随便开一个页面,去Cookies里找到,复制下来即可。

headers配置如下:

headers = {
    "User-Agent": "浏览器的UA,可以去网上抄一些",
    "Referer": "https://www.pixiv.net/",
    "Authorization": "Bearer 你的PHPSESSID",
    "X-UserId": "PHPSESSID最前面的数字部分",
    "App-Version": "web-2.0.0-24010100",
    "Cookie": "PHPSESSID=你的PHPSESSID"
}

第一步是收集图片的id,搜索页面中找到下图所示的fetch请求,即为获取图片id的接口。

直接get指定网址:https://www.pixiv.net/ajax/search/東風谷早苗,设置params如下:

params = {
    "word": 東風谷早苗,
    "order": "date"(按时间升序) // "date_d"(按时间降序),
    "mode": "all",
    "p": 页码,
    "s_mode": "s_tag",
    "type": "all",
    "lang": "zh"          #这个应该不需要
}

建议用date的排序方式,这样图片所在页码不会变,方便中断之后继续爬。mode规定了图片的类型(插画,漫画,动图),可以在这里过滤。

获取到的json结构如下:

{
  "error": false,
  "body": {
    "illustManga": {
      "data": [
        {
          "id": "129977611",    #图片id
          "title": "(リクエスト作品)東風谷早苗 足裏(東方)",
          "illustType": 0,      #0-图片,1-漫画,2-动图
          "xRestrict": 0,
          "restrict": 0,
          "sl": 4,
          "url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2025/05/03/12/45/23/129977611_p0_square1200.jpg",
          "description": "",
          "tags": [
            "東風谷早苗",
            "東方",
            "足裏",
            "裸足裏",
            "リクエスト作品"
          ],
          "userId": "194527",
          "userName": "えーあい(リクエスト受付中)",
          "width": 1024,
          "height": 1024,
          "pageCount": 8,
          "isBookmarkable": true,
          "bookmarkData": null,
          "alt": "#東風谷早苗 (リクエスト作品)東風谷早苗 足裏(東方) - えーあい(リクエスト受付中)的插画",
          "titleCaptionTranslation": {
            "workTitle": null,
            "workCaption": null
          },
          "createDate": "2025-05-03T12:45:23+09:00",
          "updateDate": "2025-05-03T12:45:23+09:00",
          "isUnlisted": false,
          "isMasked": false,
          "aiType": 2,      #0-AI时代前的作品 // 1-AI时代的非AI作品 //2-AI作品
          "visibilityScope": 0,
          "profileImageUrl": "https://i.pximg.net/user-profile/img/2024/12/26/13/11/22/26761252_e601a0da77cd561c8409befcd619a17b_50.png"
        },
        然后是接下来的图片……
        

从这里可以获取图片的元信息(一部分),可以存到数据库里了,不过图片详情页会更详细。接下来就是下载图片的环节。


2.下载图片

首先也是随便找一个图片详情页,找到如图所示的fetch请求,即为获取图片元数据的接口。

带好你的headers,直接get指定图片链接,得到json结构如下:

{
    "error": false,
    "message": "",
    "body": {
        "illustId": "32537939",
        "illustTitle": "あけまして、おめでとうございます。",
        "illustComment": "あけまして、おめでとうございます。本年もよろしくお願いいたします。(*・ω・)ノ普通加奈子様じゃね>すいませんどうしてもあの方は描けませんでした・・・どうしてもクレヨンしんちゃんのお母様になってしまう気が・・・",
        "illustType": 0,
        "createDate": "2013-01-01T00:09:00+00:00",
        "uploadDate": "2013-01-01T00:09:00+00:00",
        "urls": {
            "original": "https://i.pximg.net/img-original/img/2013/01/01/09/09/45/32537939_p0.jpg"
        },
        "tags": {
            "authorId": "550532",
            "isLocked": false,
            "tags": [
                {
                    "tag": "東方",
                    "locked": true,
                    "deletable": false,
                    "userId": "550532",
                    "translation": {
                        "en": "东方"
                    },
                    "userName": "ゆーじ"
                }
            ],
            "writable": true
        },
        "alt": "#東方 あけまして、おめでとうございます。 - ゆーじ的插画",
        "userId": "550532",
        "userName": "ゆーじ",
        "userAccount": "konakona324",
        "pageCount": 1,     #图片页数
        "bookmarkCount": 20,
        "likeCount": 26,
        "viewCount": 950
    }
}

我只保留了有用的部分,自己理解一下每一个属性的意思吧,懒得注释了()会英语就行

urls里的下载链接是重点,把里面的p0替换成p{0~pageCount-1},即可下载对应图片,记得带着headers

于是爬虫就搞好了,再加点随机等待(别爬太快了,容易封号),更换PHPSESSID(多用户),更换User-Agent(多终端)等操作就差不多好了。数据库我用的是sqlalchemy操作,图床可以自己建也可以用现成的,我用的是聚合图床,年付100元,能存10w张图片,够用了,这里不再赘述。


二、网站构建

虽然我已经学了PHP,但是对Laravel的操作完全不熟悉。于是采用了Deepseek + Qwen3混合双打式写前端,然后自己改一改逻辑。目前装了TailwindCSS,感觉已经很够用了,后续可能再装个图标包就行。目前已经实现了用户系统,随机图片和图片详情页面的开发。(用户系统就不用说了吧)

1.随机图片

对于随机图片,每次都数据库随机排序的效率实在太低,采用缓存illust_id(图片id,数据库的主键)的模式,每24小时刷新一次,用array_rand函数在列表里抽取一个图片。实现代码如下:

class IllustIdPool
{
    const CACHE_KEY = 'illust_id_pool';
    const CACHE_TTL = 86400; // 24小时

    public static function refresh()
    {
        // 获取所有有效作品的ID(pages >= 1)
        $ids = IllustDetail::where('pages', '>=', 1)
            ->pluck('illust_id')
            ->toArray();

        Cache::put(self::CACHE_KEY, $ids, self::CACHE_TTL);
    }

    public static function getRandomId()
    {
        $pool = Cache::get(self::CACHE_KEY, []);

        // 如果池为空则尝试刷新
        if (empty($pool)) {
            self::refresh();
            $pool = Cache::get(self::CACHE_KEY, []);
        }

        // 如果仍然为空则返回null
        return !empty($pool) ? $pool[array_rand($pool)] : null;
    }
}

由于多图片的作品中有很多图片没有出现早苗,所以使用位掩码储存“是早苗图片”的页码标记,在数据库中用blob(动态二进制数据)储存,兼顾效率和空间。随机页码时从位掩码中算出是早苗的页码,并用array_rand函数随机抽取。目前正在实现用户标记非早苗图片,后台人工检查并修改位掩码的机制。


2.图片详情

不用多说了,结构和随机图片页面差不多,等我把标记非早苗图片的功能做好再继续讲。(2025/5/3更新到此)

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇