我想从网站上爬取一些数据 ======================== 如何从网站爬取数据? -------------------- 实际上,\ **waifuc能爬取的网站远远不止Danbooru一个** 不过在正式开始之前,Narugo要介绍他的另一位老婆,可爱的小兔娘\ **阿米娅**\ ``amiya``\ ,同样来自\ **明日方舟**\ ``Arknights`` 以下为Narugo发癫内容:你问我为什么有这么多老婆?众所周知,二次元爱好者的老婆有无限多个,她们都是我的天使\ **😍** .. image:: amiya.png :align: center Zerochan ~~~~~~~~ `Zerochan <https://zerochan.net/>`__\ 是一个包含图像平均质量较高的网站,我们可以使用极为简单的方式进行爬取 **当我们不需要大批量的获取图像,而只需要50张图像时**\ ,可以使用以下代码实现: .. literalinclude:: zerochan_simple_50.py :language: python :linenos: 请注意,\ **此处使用**\ ``SaveExporter``\ **导出,而非之前的**\ ``TextureInversionExporter``\ **导出**\ ,关于它的作用将在本篇后续部分进行介绍 上述爬取到的图像数据将被导出到\ **指定的**\ ``./data/amiya_zerochan``\ **本地路径**\ 下,结果如下: .. image:: zerochan_simple_50.png :align: center 然而,我们会发现一个问题: Zerochan上有较多的member-only的图像,我们需要登录后才能获取它们 为此我们可以\ **使用自己的用户名**\ ``username``\ 和\ **密码**\ ``password``\ 进行鉴权,以获得更多、更优质的图像,代码如下: .. literalinclude:: zerochan_login_50.py :language: python :linenos: 再次运行,果然我们成功获取到了不少的member-only图像: .. image:: zerochan_login_50.png :align: center 不过我们又发现,这些图像很多分辨率并不高,边长超过1000像素的不多 这是因为\ **Zerochan会默认选用**\ ``large``\ **尺寸的图像**\ ,以提高下载速度 如果需要更大尺寸的图像,可以将\ **尺寸选择**\ ``select``\ 设置为\ ``full``\ ,就像这样: .. literalinclude:: zerochan_login_50_full.py :language: python :linenos: 再再次运行后,得到的将全都是全尺寸的图像 然而,依然还存在一个问题:高质量图片中很多都是官方画作,而阿米娅作为游戏的女主角,更是常作为C位出现在多人图中 **我们实际上只需要仅包含她自己的图像**\ ,这当然是没问题,只需要将\ **严格搜索模式**\ ``strict``\ 设置为\ ``True``\ 即可: .. literalinclude:: zerochan_login_50_full_strict.py :language: python :linenos: 再再再次运行,我们最终得到了来自Zerochan的高质量、全尺寸且均为阿米娅单人的图像,如下所示: .. image:: zerochan_login_50_full_strict.png :align: center Danbooru ~~~~~~~~ 理所当然,\ `Danbooru <https://danbooru.donmai.us/>`__\也是可以轻松被waifuc爬取的,使用十分简单: .. literalinclude:: danbooru_50.py :language: python :linenos: 以及,\ **在Danbooru及其类似网站可通过添加**\ ``solo``\ **关键词来直接筛选单人图像**\ ,以节省操作步骤,就像这样: .. literalinclude:: danbooru_50_solo.py :language: python :linenos: Pixiv ~~~~~ waifuc\ **支持对**\ `Pixiv <https://www.pixiv.net/>`__\ **的多种爬取方式:关键词检索、用户检索以及各种排行榜爬取** 我们可以使用\ ``PixivSearchSource``\ 数据源来进行关键词检索方式的图像数据爬取,如下所示: .. literalinclude:: pixiv_50.py :language: python :linenos: 我们也可以使用\ ``PixivUserSource``\ 数据源来进行检索方式的图像数据爬取,如下所示: .. literalinclude:: pixiv_50_user.py :language: python :linenos: 我们还可以使用\ ``PixivRankingSource``\ 数据源来进行可选择的排行榜的图像数据爬取,如下所示: .. literalinclude:: pixiv_50_ranking.py :language: python :linenos: Anime-Pictures ~~~~~~~~~~~~~~ `Anime-Pictures <https://anime-pictures.net/posts?search_tag=amiya+%28arknights%29&lang=en&page=0>`__\的图像数量不多,但是质量普遍很高 因此waifuc也同样支持对它的爬取,如下所示: .. literalinclude:: anime_pictures_50.py :language: python :linenos: Sankaku ~~~~~~~ `Sankaku <https://chan.sankakucomplex.com/>`__\的图像数量庞大且种类很多 waifuc同样支持了它,如下所示: .. literalinclude:: sankaku_50.py :language: python :linenos: Gelbooru ~~~~~~~~ `Gelbooru <https://gelbooru.com/>`__\与Danbooru的内容很相似,但在一些特定内容上有更多图像 waifuc同样它支持的爬取,如下所示: .. literalinclude:: gelbooru_50.py :language: python :linenos: Duitang ~~~~~~~ `Duitang <https://www.duitang.com/>`__\是一个来自中国的网站,因其建站时间较长,也包含不少优质的图像 应中国用户的请求,Narugo为waifuc添加了针对堆糖(duitang)的支持,如下所示: .. literalinclude:: duitang_50.py :language: python :linenos: 其余受支持的图像站 ~~~~~~~~~~~~~~~~~~ 除了上述的这些外,waifuc还支持了大量其他的图像站。\ **所有受支持图像站**\ 如下所示: - `ATFBooruSource <https://booru.allthefallen.moe/>`__ - `AnimePicturesSource <https://anime-pictures.net/>`__ - `DanbooruSource <https://danbooru.donmai.us/>`__ - `DerpibooruSource <https://derpibooru.org/>`__ - `DuitangSource <https://www.duitang.com/>`__ - `E621Source <https://e621.net/>`__ - `E926Source <https://e926.net/>`__ - `FurbooruSource <https://furbooru.com/>`__ - `GelbooruSource <https://gelbooru.com/>`__ - `Huashi6Source <https://www.huashi6.com/>`__ - `HypnoHubSource <https://hypnohub.net/>`__ - `KonachanNetSource <https://konachan.net/>`__ - `KonachanSource <https://konachan.com/>`__ - `LolibooruSource <https://lolibooru.moe/>`__ - `PahealSource <https://rule34.paheal.net/>`__ - `PixivRankingSource <https://pixiv.net/>`__ - `PixivSearchSource <https://pixiv.net/>`__ - `PixivUserSource <https://pixiv.net/>`__ - `Rule34Source <https://rule34.xxx/>`__ - `SafebooruOrgSource <https://safebooru.org/>`__ - `SafebooruSource <https://safebooru.donmai.us/>`__ - `SankakuSource <https://chan.sankakucomplex.com/>`__ - `TBIBSource <https://tbib.org/>`__ - `WallHavenSource <https://wallhaven.cc/>`__ - `XbooruSource <https://xbooru.com/>`__ - `YandeSource <https://yande.re/>`__ - `ZerochanSource <https://www.zerochan.net/>`__ (关于上述\ ``Source``\ 的更多信息和使用细节,详见waifuc源代码) 我想从多个网站上爬取数据 ------------------------ 在一些情况中,我们希望从多个网站获取图像数据 比如下面的情况中,我们需要从Danbooru上获取30张图像,再从zerochan上获取30张图像 为满足此类需求,waifuc提供了\ ``Source``\ 间的串并联操作,可以通过串联\ ``+``\ 和并联\ ``|``\ 将多个数据源进行集成 例如在上面的需求中,我们可以将Danbooru数据源和Zerochan数据源进行串联,形成新的数据源,如下所示: .. literalinclude:: source_concat.py :language: python :linenos: 上述代码将先从Danbooru爬取30张图像,再从Zerochan爬取30张图像 这样,我们可以得到如下的数据集: .. image:: source_concat.png :align: center 除此之外,在部分情况下,我们可能并不会提前设计好从各个数据源爬取多少图像,而是希望能尽量多地从不同数据源爬取,并最终得到一个需要的总数量。在这种情况下,我们可以使用并联操作,如下所示: .. literalinclude:: source_union.py :language: python :linenos: 在这一次爬取中,将从两个站中随机选择进行爬取,直至爬取到60张图像为止 因此实际上最终获得的数据集并不确定,以下数据集仅供参考: .. image:: source_union.png :align: center 所有的\ ``Source``\ 间也可以进行复杂的嵌套运算,以构建一个复杂的数据源: .. literalinclude:: source_complex.py :language: python :linenos: 此处就构建了一个复杂的数据源 ``s = s_zerochan[:50] + (s_db | s_pixiv)[:50]``\ ,具体功能为: - 先从Zerochan上爬取50张图像 - 再从Danbooru和Pixiv上随机爬取,共计50张图像 因此这个数据源最终将爬取以Zerochan为主的100张图像 ``Source``\ 的串并联操作还可以在\ ``attach``\ 方法之后进行,即进行预处理后,再进行串并联 例如: .. literalinclude:: source_complex_attach.py :language: python :linenos: 上述代码的效果是: - 从Zerochan和Danbooru两个网站上爬取图像 - Zerochan的图像需要进行去背景处理,而Danbooru上的不需要 - 两个数据源总计爬取60张图像 得到的结果如下所示,可以看到,zerochan的图像都进行了去背景处理: .. image:: source_complex_attach.png :align: center 通过以上演示可以了解,串并联是\ ``Source``\ 的一项重要特性,合理利用将让配置多样化且极富灵活性 为什么会有这么多json文件? -------------------------- 如果你坚持读到了这里,你应该会注意到示例图中的一个问题 上述所有使用\ ``SaveExporter``\ 进行保存的数据集,每个图像文件都有与其同名的json文件 你一定会感到好奇,这些json文件是做什么用的?我该如何关闭它们的生成? 该部分将对此一一作出解答 首先,我们打开一个其中的json文件\ ``.danbooru_6814120_meta.json``\ ,并查看里面的内容: .. collapse:: A Sample Meta-Information JSON .. literalinclude:: meta_json.json :language: json :linenos: 内容比较长,\ **简单来说,这是一个存储图像文件元数据**\ ``meta-information``\ **文件** 它包含了以下的信息: - 来自danbooru网站的图像信息,即图像的tag、尺寸、ID、上传时间等 - 图像的url信息,即图像是从哪里被下载的 - 图像的命名信息,即图像将被保存为什么文件名 - 图像的tag信息,即当生成训练用的数据集时,其tag将包含哪些 这些信息在一些处理环节中,将发挥其应有的作用 例如tag信息,生成该信息需要从网站进行爬取,或者使用tagger进行打标,而该信息将在产生LoRA训练数据集时进行写入 因此在waifuc中,默认对json文件进行保存,并且可以使用\ ``SaveExporter``\ 进行保存 为了充分利用这些元数据,我们\ **可以使用**\ ``LocalSource``\ **将包含json文件的本地数据集通过**\ ``SaveExporter``\ **再次加载**\ : .. literalinclude:: local.py :language: python :linenos: 以上代码可以将包含元数据的本地数据集再次载入,并按照LoRA训练数据集的格式进行再次保存,即只保留存储标注信息的txt文件 处理后的数据集如下所示: .. image:: local_to_dataset.png :align: center .. note:: - \ ``LocalSource``\ **对所有本地的数据集都可进行加载,并不一定需要元数据** - 若没有json文件,得到的图像数据将不包含初始元数据,这意味着tag等信息必须重新生成 - \ ``LocalSource``\ **作为一种**\ ``Source``\ **,也可以进行串并联操作,因此你可以同时使用来自网络和本地的图像构建数据集** 当你确定只需要图像,不需要任何元数据时,设置参数\ ``no_meta``\为\ ``True``\来实现这一点: .. literalinclude:: save_no_meta.py :language: python :linenos: 这样的代码将不会保存任何json文件,将只爬取50张图像,如下所示: .. image:: save_no_meta.png :align: center 我不想将图像保存到硬盘上,如何直接使用它们? -------------------------------------------- 你可能不希望将图像文件缓存到硬盘上,而是直接在内存中处理以节省时间 .. literalinclude:: iterate_usage.py :language: python :linenos: 没错,\ **所有**\ ``Source``\ **都是可以作为List进行遍历操作的** 而其中的item,其类型定义如下: .. literalinclude:: item_definition.py :language: python :linenos: 不难发现,每一个item的结构十分简单,包含一个\ ``PIL.Image``\ 结构的图像对象和一个用于存储元信息的\ ``meta``\项。 获取到item项后,你将可以自行使用其图像对象和元数据定制所需要的操作。