进阶 docs.stashapp.cc 2026-10-20 02:59:21 · 13 阅读
第23章 为 Stash 社区贡献爬虫
贡献爬虫¶
你可以在该仓库中创建 PR 将爬虫贡献给社区。
XPath 爬虫模板¶
最基础的 XPath 爬虫模板可以在 CommunityScrapers 仓库中找到。
爬虫配置文件格式¶
name:
performerByName:
<单个爬虫配置>
performerByFragment:
<单个爬虫配置>
performerByURL:
<多个爬虫 URL 配置>
sceneByName:
<单个爬虫配置>
sceneByQueryFragment:
<单个爬虫配置>
sceneByFragment:
<单个爬虫配置>
sceneByURL:
<多个爬虫 URL 配置>
groupByURL:
<多个爬虫 URL 配置>
galleryByFragment:
<单个爬虫配置>
galleryByURL:
<多个爬虫 URL 配置>
imageByFragment:
<单个爬虫配置>
imageByURL:
<多个爬虫 URL 配置>
<其他配置>
name 为必填项,其他顶级字段均为可选。包含哪些顶级字段决定了爬虫具备哪些能力。
任意顶级字段中的爬虫配置至少必须包含一个 action 字段。其他字段是否必填取决于 action 字段的值。
抓取类型及其所需字段如下表所示:
行为
必需配置
Performer 编辑页面“Scrape...”下拉按钮中的爬虫
有效的 performerByName 和 performerByFragment 配置。
从 URL 抓取 Performer
具有匹配 URL 的有效 performerByURL 配置。
Scene 编辑页面查询下拉按钮中的爬虫
有效的 sceneByName 和 sceneByQueryFragment 配置。
Scene 编辑页面“Scrape...”下拉按钮中的爬虫
有效的 sceneByFragment 配置。
从 URL 抓取 Scene
具有匹配 URL 的有效 sceneByURL 配置。
从 URL 抓取 Group
具有匹配 URL 的有效 groupByURL 配置。注意:movieByURL 也受支持但已弃用。
Gallery 编辑页面“Scrape...”下拉按钮中的爬虫
有效的 galleryByFragment 配置。
从 URL 抓取 Gallery
具有匹配 URL 的有效 galleryByURL 配置。
基于 URL 的抓取接受多个抓取配置,且每个配置都需要一个 url 字段。Stash 会遍历这些配置,尝试将输入的 URL 与配置中的 url 字段进行匹配。它会执行第一个输入 URL 包含 url 字段值的抓取配置。
操作¶
Script¶
执行脚本以完成抓取。此操作需要 script 字段,它接受一个字符串参数列表。示例如下:
action: script
script:
- python
- iafdScrape.py
- query
如果脚本指定了 python 可执行文件,Stash 会为你系统找到正确的 python 可执行文件,即 python 或 python3。例如,此配置可能执行 python iafdScrape.py query 或 python3 iafdScrape.py query。
系统会优先查找 python3,如果未找到则检查 python。如果两者均未找到,将会报错。
Stash 将数据发送到脚本进程的 stdin 流,并期望输出流到 stdout 流。任何错误和进度消息都应输出到 stderr。
脚本根据抓取类型接收输入并期望输出,具体详情见下表:
抓取类型
输入
输出
performerByName
{"name": ""}
JSON 编码的 performer 片段数组(至少包含 name)
performerByFragment
JSON 编码的 performer 片段
JSON 编码的 performer 片段
performerByURL
{"url": ""}
JSON 编码的 performer 片段
sceneByName
{"name": ""}
JSON 编码的 scene 片段数组
sceneByQueryFragment, sceneByFragment
JSON 编码的 scene 片段
JSON 编码的 scene 片段
sceneByURL
{"url": ""}
JSON 编码的 scene 片段
groupByURL
{"url": ""}
JSON 编码的 group 片段
galleryByFragment
JSON 编码的 gallery 片段
JSON 编码的 gallery 片段
galleryByURL
{"url": ""}
JSON 编码的 gallery 片段
imageByFragment
JSON 编码的 image 片段
JSON 编码的 image 片段
imageByURL
{"url": ""}
JSON 编码的 image 片段
对于 performerByName,返回的 performer 片段中仅 name 为必填。整个对象会回传给 performerByFragment 以抓取特定 performer,因此可以包含其他字段以辅助抓取。例如,可以填写 url 字段指向特定的 performer 页面,然后 performerByFragment 可以利用该值进行提取。
Performer 爬虫的 Python 示例:
import json
import sys
import string
def readJSONInput():
input = sys.stdin.read()
return json.loads(input)
def searchPerformer(name):
# 在此处执行抓取 - 使用 name 进行查询
# 填充输出
ret = []
# 展示找到一个 performer 的示例
p = {}
p['name'] = "some name"
p['url'] = "performer url"
ret.append(p)
return ret
def scrapePerformer(input):
ret = []
# 从输入获取 url
url = input['url']
return scrapePerformerURL(url)
def debugPrint(t):
sys.stderr.write(t + "\n")
def scrapePerformerURL(url):
debugPrint("Reading url...")
debugPrint("Parsing html...")
# 解析 html
# 填充 performer 详情 - 单个对象
ret = {}
ret['name'] = "fred"
ret['aliases'] = "freddy"
ret['ethnicity'] = ""
# 等等
return ret
# 读取输入
i = readJSONInput()
if sys.argv[1] == "query":
ret = searchPerformer(i['name'])
print(json.dumps(ret))
elif sys.argv[1] == "scrape":
ret = scrapePerformer(i)
print(json.dumps(ret))
elif sys.argv[1] == "scrapeURL":
ret = scrapePerformerURL(i['url'])
print(json.dumps(ret))
scrapeXPath¶
此操作使用 xpath 配置解析来抓取网页。此操作对 performerByFragment 无效。
此操作要求顶层 xPathScrapers 配置已填充。scraper 字段为必填,且必须与 xPathScrapers 中配置的爬虫名称匹配。示例:
sceneByURL:
- action: scrapeXPath
url:
- pornhub.com/view_video.php
scraper: sceneScraper
上述配置要求 sceneScraper 存在于 xPathScrapers 配置中。
XPath 抓取配置指定了对象字段与 xpath 选择器之间的映射。xpath 爬虫抓取相应的 URL 并使用 xpath 填充对象字段。
scrapeJson¶
此操作的工作方式与 scrapeXPath 相同,但使用映射的 json 配置进行解析。它使用顶层 jsonScrapers 配置。此操作对 performerByFragment 无效。
JSON 抓取配置指定了对象字段与 GJSON 选择器之间的映射。JSON 爬虫抓取相应的 URL 并使用 GJSON 解析返回的 JSON 对象以填充对象字段。
scrapeXPath 和 scrapeJson 与 performerByName 的使用¶
对于 performerByName,还必须存在 queryURL 字段。该字段用于执行 performer 名称的搜索查询 URL。占位符字符串序列 {} 会被替换为 performer 名称搜索字符串。为了使后续的 performer 抓取生效,必须用与 performerByURL 抓取配置中给定的 URL 匹配的 performer 页面 URL 填充 url 字段。示例:
name: Boobpedia
performerByName:
action: scrapeXPath
queryURL: http://www.boobpedia.com/wiki/index.php?title=Special%3ASearch&search={}&fulltext=Search
scraper: performerSearch
performerByURL:
- action: scrapeXPath
url:
- boobpedia.com/boobs/
scraper: performerScraper
xPathScrapers:
performerSearch:
performer:
Name: # name 元素
URL: # 匹配上述 boobpedia.com/boobs/ URL 的 URL 元素
performerScraper:
# ... performer 爬虫详情 ...
scrapeXPath 和 scrapeJson 与 sceneByFragment 和 sceneByQueryFragment 的使用¶
对于 sceneByFragment 和 sceneByQueryFragment,还必须存在 queryURL 字段。该字段用于构建 scene 的查询 URL。对于 sceneByFragment,queryURL 字段支持以下占位符字段:
{checksum} - scene 的 MD5 校验和
{oshash} - scene 的 oshash
{phash} - scene 的 phash
{filename} - scene 的基础文件名
{title} - scene 的标题
{url} - scene 的 url
可以通过添加 queryURLReplace 部分来操作这些占位符字段的值,其中包含一个从占位符字段到 regex 配置的映射,该配置使用与下文所述的 replace 后处理操作相同的格式。
例如:
sceneByFragment:
action: scrapeJson
scraper: sceneQueryScraper
queryURL: https://metadataapi.net/api/scenes?parse={filename}&limit=1
queryURLReplace:
filename:
- regex:
with:
上述配置将从 queryURL 的值进行抓取,其中 {filename} 在经历 regex 替换操作后,会被替换为 scene 的基础文件名。
scrapeXPath 和 scrapeJson 与 ByURL 的使用¶
对于 sceneByURL, performerByURL, galleryByURL,如果想使用 queryURLReplace,也可以存在 queryURL 字段。其功能与 sceneByFragment 相同,但仅可用的占位符字段是 url:
{url} - scene/performer/gallery 的 url
sceneByURL:
- action: scrapeJson
url:
- metartnetwork.com
scraper: sceneScraper
queryURL: "{url}"
queryURLReplace:
url:
- regex: '^(?:.+\.)?([^.]+)\.com/.+movie/(\d+)/(\w+)/?$'
with: https://www.$1.com/api/movie?name=$3&date=$2
Stash¶
可以配置另一个 stash 服务器作为抓取源。此操作仅适用于 performerByName, performerByFragment, sceneByName, sceneByQueryFragment 和 sceneByFragment 类型。此操作要求顶层 stashServer 字段已配置。
stashServer 包含一个指向远程 stash 服务器的 url 字段。
可以使用 username:password@host 格式将用户名和密码嵌入该字符串中。
或者,可以使用 apiKey 字段来对远程 stash 服务器进行身份验证。
下方的 stash 抓取配置示例:
name: stash
performerByName:
action: stash
performerByFragment:
action: stash
sceneByFragment:
action: stash
sceneByName:
action: stash
sceneByQueryFragment:
action: stash
stashServer:
apiKey:
url: http://stashserver.com:9999
XPath 和 JSON 爬虫配置¶
顶层 xPathScrapers 字段包含 xpath 抓取配置,可以自由命名。它们在 scrapeXPath 爬虫的 scraper 字段中被引用。
同样,顶层 jsonScrapers 字段包含 json 抓取配置。
统称为映射抓取配置。
映射抓取配置可能包含 common 字段,并根据其配置的抓取类型必须包含 performer, scene, group 或 gallery。
在 performer/scene/group/gallery 字段内部是与 performer/scene 对象上的 golang 字段对应的键值对。这些字段区分大小写。
这些字段的值可以是简单的选择器值,告诉系统从何处获取字段值,也可以是更高级的配置(见下文)。例如,对于 xpath 配置:
performer:
Name: //h1[@itemprop="name"]
这将把返回的 performer 的 Name 属性设置为匹配 ... 的元素文本内容。
对于 json 配置:
performer:
Name: data.name
值也可以是子对象。如果是子对象,则必须将 selector 设置为子对象的选择器键。例如,使用与上述相同的 xpath:
performer:
Name:
selector: //h1[@itemprop="name"]
postProcess:
# 后处理配置值
固定属性值¶
或者,可以将属性值设置为固定值,而不是从网页抓取。这可以通过用 fixed 替换 selector 来实现。例如:
performer:
Gender:
fixed: Female
输入 URL 占位符¶
可以在固定值和选择器表达式中使用 {inputURL} 和 {inputHostname} 占位符来访问用于抓取内容的原始 URL 信息。
{inputURL}¶
{inputURL} 占位符提供对完整 URL 的访问权限。当你希望将源 URL 作为抓取数据的一部分返回或引用时,这很有用。
例如:
scene:
URL:
fixed: "{inputURL}"
Title:
selector: //h1[@class="title"]
当从 https://example.com/scene/12345 抓取时,{inputURL} 占位符将被替换为 https://example.com/scene/12345。
{inputHostname}¶
{inputHostname} 占位符从 URL 中提取主机名。当你需要引用域名而无需手动解析 URL 时,这很有用。
例如:
scene:
Studio:
fixed: "{inputHostname}"
Details:
selector: //div[@data-domain="{inputHostname}"]//p[@class="description"]
当从 https://example.com/scene/12345 抓取时,{inputHostname} 占位符将被替换为 example.com。
这些占位符也可以在选择器中用于更高级的用途:
scene:
Details:
selector: //div[@data-url="{inputURL}"]//p[@class="description"]
Site:
selector: //div[@data-host="{inputHostname}"]//span[@class="site-name"]
⚠️ 注意:这些占位符代表实际用于获取内容的 URL,这是在应用任何 URL 替换之后的结果。
公共片段¶
common 字段用于配置可以在选择器字符串中引用的选择器片段。这些是键值对,其中键是引用片段的字符串,值是片段将被替换成的字符串。例如:
common:
$infoPiece: //div[@class="infoPiece"]/span
performer:
Measurements: $infoPiece[text() = 'Measurements:']/../span[@class="smallInfo"]
Measurements xpath 字符串将 $infoPiece 替换为 //div[@class="infoPiece"]/span,结果为://div[@class="infoPiece"]/span[text() = 'Measurements:']/../span[@class="smallInfo"]。
⚠️ 注意:不支持递归公共片段。
在一个公共片段中引用另一个公共片段会导致错误。例如:
common:
$info: //div[@class="info"]
# 在 $models 中引用 $info 会导致错误
$models: $info/a[@class="model"]
scene:
Title: $info/h1
Performers:
Name: $models
URL: $models/@href
后处理选项¶
后处理操作包含在 postProcess 键中。后处理操作按照指定顺序执行。可用的后处理操作包括:
javascript:接受一个 javascript 代码块,必须返回字符串值。输入字符串在 value 变量中声明。如果在编译或运行脚本时发生错误,则返回原始值。
示例:
performer:
Name:
selector: //div[@class="example element"]
postProcess:
- javascript: |
// 首字母大写
if (value && value.length) {
return value[0].toUpperCase() + value.substring(1)
}
我们使用 goja javascript 引擎,它缺少一些内置方法,并且可能与其他现代 javascript 实现不一致。
feetToCm:将包含英尺和英寸数字的字符串转换为厘米。查找最多两个独立的整数,将第一个解释为英尺数,第二个解释为英寸数。数字可以由任何非数字字符(包括 . 字符)分隔。它不处理小数。例如,6.3 和 6ft3.3 在转换为厘米前都会被解释为 6 英尺 3 英寸。
lbToKg:将包含磅的字符串转换为千克。
map:包含从输入值到输出值的映射。当值匹配其中一个输入值时,它会被替换为匹配的出口值。如果没有匹配的值,则值保持不变。
示例:
performer:
Gender:
selector: //div[@class="example element"]
postProcess:
- map:
F: Female
M: Male
Height:
selector: //span[@id="height"]
postProcess:
- feetToCm: true
Weight:
selector: //span[@id="weight"]
postProcess:
- lbToKg: true
获取选定 div 元素的内容,并将返回的值设置为:
如果抓取值为 F,则为 Female;
如果抓取值为 M,则为 Male。
高度和重量从选定的 spans 中提取并转换为 cm 和 kg。
parseDate:如果存在,该值为使用 go 的参考日期(2006-01-02)的日期格式。例如,如果示例日期是 14-Mar-2003,则日期格式为 02-Jan-2006。详见 time.Parse 文档。如果存在,爬虫会将输入字符串转换为日期,然后转换为 stash 使用的字符串格式(YYYY-MM-DD)。字符串 "Today" 和 "Yesterday" 会被匹配(不区分大小写)并由爬虫转换,因此你无需编辑/替换它们。
通过选择 unix 作为日期格式,也可以解析 Unix 时间戳(示例:1660169451)。
示例:
Date:
selector: //div[@class="value epoch"]/text()
postProcess:
- parseDate: unix
subtractDays:如果设置为 true,则从当前日期中减去该值的天数,并以 stash 的日期格式返回结果日期。
示例:
Date:
selector: //strong[contains(text(),"Added:")]/following-sibling::text()
postProcess:
- replace:
- regex: (\d+)\sdays\sago.+
with: $1
- subtractDays: true
replace:包含子对象数组。每个子对象必须包含 regex 和 with 字段。regex 字段是要替换的 regex 模式,with 是要替换成的字符串。$ 用于引用捕获组 - $1 是第一个捕获组,$2 是第二个,依此类推。替换按数组顺序执行。
示例:
CareerLength:
selector: $infoPiece[text() = 'Career Start and End:']/../span[@class="smallInfo"]
postProcess:
- replace:
- regex: \s+to\s+
with: "-"
将 2001 to 2003 替换为 2001-2003。
subScraper:如果存在,子爬虫将在所有其他后处理完成后、在 parseDate 之前执行。它获取值并执行 http 请求,使用该值作为 URL。subScraper 配置内部包含嵌套的抓取配置。这允许你遍历其他网页以获取所需的属性值。更多信息和示例请查看 #370、#606
此外,有许多固定的后处理字段,在属性级别指定(不在 postProcess 中),并在 postProcess 操作之后执行:
concat:如果 xpath 匹配多个元素,且存在 concat,则所有元素将连接在一起。
split:concat 的反操作。使用给定的分隔符将字符串拆分为更多元素。更多信息和示例请查看 PR #579
示例:
Tags:
Name:
selector: //span[@class="list_attributes"]
split: ","
将位于 span 中的逗号分隔标签列表拆分并返回标签。
为了向后兼容,replace、subscraper 和 parseDate 也允许作为属性的键。
属性的后处理按以下顺序执行:concat、replace、subscraper、parseDate 然后 split。
XPath 资源:¶
在 Firefox 中测试 XPaths:https://addons.mozilla.org/en-US/firefox/addon/try-xpath/
XPath 速查表:https://devhints.io/xpath
GJSON 资源:¶
GJSON 路径语法:https://github.com/tidwall/gjson/blob/master/SYNTAX.md
调试支持¶
要将爬虫请求接收到的 html/json 打印到日志文件,请在爬虫 yml 文件中添加以下内容:
debug:
printHTML: true
CDP 支持¶
某些网站提供的内容无法仅通过原始 html 文件进行抓取。这些网站使用 javascript 动态加载内容。因此,直接的 xpath 抓取在这些网站上不会生效。有一个选项可以使用 Chrome DevTools Protocol 使用 Chrome 实例加载网页,然后抓取结果。
可以通过在 yml 配置的根目录下添加以下内容来为特定的抓取配置启用 Chrome CDP 支持:
driver:
useCDP: true
可选地,你可以在 driver 部分添加 sleep 值。这指定了爬虫在加载网站后执行抓取前需要等待的时间(以秒为单位)。这是因为某些站点需要更多时间来加载脚本。如果未设置,该值默认为 2 秒。
当 useCDP 设置为 true 时,stash 会执行或连接到一个 Chrome 实例。行为由用户配置中的 Chrome CDP 路径设置决定。如果留空,stash 会尝试在路径环境中查找 Chrome 可执行文件,如果找不到则会失败。
Chrome CDP 路径可以设置为 chrome 可执行文件的路径,或远程 chrome 实例的 http(s) 地址(例如:http://localhost:9222/json/version)。也可以使用 docker 容器作为远程实例,强烈推荐 chromedp/headless-shell 镜像。
CDP 点击支持¶
使用 CDP 时,你可以使用 driver 部分的 clicks 部分对需要折叠或切换的元素执行鼠标点击。每个点击元素都有一个 xpath 值,保存你需要点击的按钮/元素的 XPath,以及一个可选的 sleep 值,指定点击后等待的时间(秒)。
如果未设置 sleep 值,默认为 2 秒。
以下是使用 clicks 的演示爬虫。
name: clickDemo # 仅针对单个 URL 的演示
sceneByURL:
- action: scrapeXPath
url:
- https://getbootstrap.com/docs/4.3/components/collapse/
scraper: sceneScraper
xPathScrapers:
sceneScraper:
scene:
Title: //head/title
Details: # 显示页面 Multiple targets 示例中可见 div 的 id
selector: //div[@class="bd-example"]//div[@class="multi-collapse collapse show"]/@id
concat: "\n\n"
driver:
useCDP: true
sleep: 1
clicks: # 演示用法,多次开启/关闭切换
- xpath: //a[@href="#multiCollapseExample1"] # 切换第一个元素
- xpath: //button[@data-target="#multiCollapseExample2"] # 切换第二个元素
sleep: 4
- xpath: //a[@href="#multiCollapseExample1"] # 关闭第一个元素
sleep: 1
- xpath: //button[@data-target="#multiCollapseExample2"] # 关闭第二个元素
- xpath: //button[@data-target="#multiCollapseExample2"] # 开启第二个元素
⚠️ 注意:每个点击会增加额外的 clicks sleep 秒延迟,因此上述操作使页面加载时间增加了 2+4+1+2+2=11 秒。
Cookie 支持¶
在某些网站上,需要使用 cookies 来绕过欢迎消息或其他类型的保护。Stash 支持为直接 xpath 爬虫和基于 CDP 的爬虫设置 cookies。由于实现问题,用法略有不同。
要使用 cookie 功能,需要在 driver 部分添加 cookies 子部分。
每个 cookie 元素可以包含一个 CookieURL 和若干 Cookies。
CookieURL 仅在使用直接/原生爬虫方法时需要。它是我们从抓取站点期望的请求 url。它必须与我们试图设置的 cookies 在同一域中,否则该组中的所有 cookies 都会设置失败。如果 CookieURL 不是有效的 URL,该组中的 cookies 也会失败。
Cookies 是我们要实际设置的 cookies。使用 CDP 时,这是唯一需要的部分。它们具有 Name, Value, Domain, Path 值。
在以下示例中,我们使用 cookies 为一个使用直接/原生 xpath 爬虫的网站配置。我们期望请求来自 https://www.example.com 和 https://api.somewhere.com,并查找 _warning 和 _warn cookie。还设置了 _test2 cookie 仅作演示。
driver:
cookies:
- CookieURL: "https://www.example.com"
Cookies:
- Name: "_warning"
Domain: ".example.com"
Value: "true"
Path: "/"
- Name: "_test2"
Value: "123412"
Domain: ".example.com"
Path: "/"
- CookieURL: "https://api.somewhere.com"
Cookies:
- Name: "_warn"
Value: "123"
Domain: ".somewhere.com"
使用 CDP 时的相同功能如下所示:
driver:
useCDP: true
cookies:
- Cookies:
- Name: "_warning"
Domain: ".example.com"
Value: "true"
Path: "/"
- Name: "_test2"
Value: "123412"
Domain: ".example.com"
Path: "/"
- Cookies:
- Name: "_warn"
Value: "123"
Domain: ".somewhere.com"
在某些网站上,cookie 本身的值并不重要。在这种情况下,我们可以使用 ValueRandom 属性代替 Value。与 Value 不同,ValueRandom 需要一个大于 0 的整数值,该值指示 cookie 字符串的长度。
在以下示例中,我们将调整之前的 cookies 以使用 ValueRandom。我们将 _test2 cookie 设置为随机生成长度为 6 个字符的值,将 _warn cookie 设置为长度为 3。
driver:
cookies:
- CookieURL: "https://www.example.com"
Cookies:
- Name: "_warning"
Domain: ".example.com"
Value: "true"
Path: "/"
- Name: "_test2"
ValueRandom: 6
Domain: ".example.com"
Path: "/"
- CookieURL: "https://api.somewhere.com"
Cookies:
- Name: "_warn"
ValueRandom: 3
Domain: ".somewhere.com"
在开发爬虫时,你可以通过添加以下内容来查看网站设置的 cookies:
如果使用直接 xpath 爬虫,添加 CookieURL
如果使用 CDP 爬虫,添加 Domain
并在调试模式下查看日志/控制台。
Headers¶
使用爬虫时可以发送请求头。
Headers 可以设置在 driver 部分,并适用于普通、启用 CDP 和 JSON 爬虫。
它们由 Key 和 Value 组成。如果 Key 为空或未定义,则该 header 被忽略。
driver:
headers:
- Key: User-Agent
Value: My Stash Scraper
- Key: Authorization
Value: Bearer ds3sdfcFdfY17p4qBkTVF03zscUU2glSjWF17bZyoe8
headers 在应用 stash 的 User-Agent 配置选项后设置。
这意味着从爬虫设置 User-Agent header 会覆盖配置文件中的设置。
XPath 爬虫示例¶
下面展示了一个 performer 和 scene xpath 爬虫作为示例:
name: Pornhub
performerByURL:
- action: scrapeXPath
url:
- pornhub.com
scraper: performerScraper
sceneByURL:
- action: scrapeXPath
url:
- pornhub.com/view_video.php
scraper: sceneScraper
xPathScrapers:
performerScraper:
common:
$infoPiece: //div[@class="infoPiece"]/span
performer:
Name: //h1[@itemprop="name"]
Birthdate:
selector: //span[@itemprop="birthDate"]
parseDate: Jan 2, 2006
Twitter: //span[text() = 'Twitter']/../@href
Instagram: //span[text() = 'Instagram']/../@href
Measurements: $infoPiece[text() = 'Measurements:']/../span[@class="smallInfo"]
Height:
selector: $infoPiece[text() = 'Height:']/../span[@class="smallInfo"]
postProcess:
- replace:
- regex: .*\((\d+) cm\)
with: $1
Ethnicity: $infoPiece[text() = 'Ethnicity:']/../span[@class="smallInfo"]
FakeTits: $infoPiece[text() = 'Fake Boobs:']/../span[@class="smallInfo"]
Piercings: $infoPiece[text() = 'Piercings:']/../span[@class="smallInfo"]
Tattoos: $infoPiece[text() = 'Tattoos:']/../span[@class="smallInfo"]
CareerLength:
selector: $infoPiece[text() = 'Career Start and End:']/../span[@class="smallInfo"]
postProcess:
- replace:
- regex: \s+to\s+
with: "-"
sceneScraper:
common:
$performer: //div[@class="pornstarsWrapper"]/a[@data-mxptype="Pornstar"]
$studio: //div[@data-type="channel"]/a
scene:
Title: //div[@id="main-container"]/@data-video-title
Tags:
Name: //div[@class="categoriesWrapper"]//a[not(@class="add-btn-small ")]
Performers:
Name: $performer/@data-mxptext
URL: $performer/@href
Studio:
Name: $studio
URL: $studio/@href
Details: //div[@class="studioDescription"]
Aliases: //div[@class="studioAliases"]/span
Tags:
Name: //div[@class="studioTags"]/a
更多示例请参见 #333。
JSON 爬虫示例¶
下面是 ThePornDB 的 performer 和 scene 爬虫:
name: ThePornDB
performerByName:
action: scrapeJson
queryURL: https://api.metadataapi.net/performers?q={}
scraper: performerSearch
performerByURL:
- action: scrapeJson
url:
- https://api.metadataapi.net/performers/
scraper: performerScraper
sceneByURL:
- action: scrapeJson
url:
- https://api.metadataapi.net/scenes/
scraper: sceneScraper
sceneByFragment:
action: scrapeJson
queryURL: https://api.metadataapi.net/scenes?parse={filename}&hash={oshash}&limit=1
scraper: sceneQueryScraper
queryURLReplace:
filename:
- regex: "[^a-zA-Z\\d\\-._~]" # 清理文件名以构建有效 url
with: "." # "%20"
- regex: HEVC
with:
- regex: x265
with:
- regex: \.+
with: "."
jsonScrapers:
performerSearch:
performer:
Name: data.#.name
URL:
selector: data.#.id
postProcess:
- replace:
- regex: ^
with: https://api.metadataapi.net/performers/
performerScraper:
common:
$extras: data.extras
performer:
Name: data.name
Gender: $extras.gender
Birthdate: $extras.birthday
Ethnicity: $extras.ethnicity
Height:
selector: $extras.height
postProcess:
- replace:
- regex: cm
with:
Measurements: $extras.measurements
Tattoos: $extras.tattoos
Piercings: $extras.piercings
Aliases: data.aliases
Image: data.image
sceneScraper:
common:
$performers: data.performers
scene:
Title: data.title
Details: data.description
Date: data.date
URL: data.url
Image: data.background.small
Performers:
Name: data.performers.#.name
Studio:
Name: data.site.name
URL: data.site.url
Details: data.site.description
Aliases: data.site.aliases
Tags:
Name: data.site.tags.#.name
Tags:
Name: data.tags.#.tag
sceneQueryScraper:
common:
$data: data.0
$performers: data.0.performers
scene:
Title: $data.title
Details: $data.description
Date: $data.date
URL: $data.url
Image: $data.background.small
Performers:
Name: $data.performers.#.name
Studio:
Name: $data.site.name
URL: $data.site.url
Details: $data.site.description
Aliases: $data.site.aliases
Tags:
Name: $data.site.tags.#.name
Tags:
Name: $data.tags.#.tag
driver:
headers:
- Key: User-Agent
Value: Stash JSON Scraper
- Key: Authorization
Value: Bearer lPdwFdfY17p4qBkTVF03zscUU2glSjdf17bZyoe # 在此处使用实际的 API Key
# 最后更新于 2021 年 4 月 7 日
对象字段¶
Gallery¶
Code
Date
Details
Performers(参见 Performer 字段)
Photographer
Rating
Studio(参见 Studio 字段)
Tags(参见 Tag 字段)
Title
URLs
⚠️ 重要:Title 字段为必填项。
Group¶
Aliases
BackImage
Date
Director
Duration
FrontImage
Name
Rating
Studio(参见 Studio 字段)
Synopsis
Tags(参见 Tag 字段)
URLs
⚠️ 重要:Name 字段为必填项。
Image¶
Code
Date
Details
Performers(参见 Performer 字段)
Photographer
Rating
Studio(参见 Studio 字段)
Tags(参见 Tag 字段)
Title
URLs
Performer¶
Aliases
Birthdate
CareerLength
Circumcised
Country
DeathDate
Details
Disambiguation
Ethnicity
EyeColor
FakeTits
Gender
HairColor
Height
Measurements
Name
PenisLength
Piercings
Tags(参见 Tag 字段)
Tattoos
URLs
Weight
⚠️ 重要:Name 字段为必填项。
⚠️ 注意:Gender 必须是 male, female, transgender_male, transgender_female, intersex, non_binary 之一(不区分大小写)。
Scene¶
Code
Date
Details
Director
Groups(参见 Group 字段)
Image
Performers(参见 Performer 字段)
Studio(参见 Studio 字段)
Tags(参见 Tag 字段)
Title
URLs
⚠️ 重要:仅当 fileless 时,Title 字段为必填项。
Studio¶
Aliases
Details
Name
Tags(参见 Tag 字段)
URL
⚠️ 重要:Name 字段为必填项。
Tag¶
Name
⚠️ 重要:Name 字段为必填项。