跳到主要內容

Scrapling

使用 Scrapling 進行網頁抓取 - 通過 CLI 和 Python 實現 HTTP 獲取、隱蔽瀏覽器自動化、Cloudflare 繞過以及蜘蛛爬取。

技能元數據

來源可選 — 使用 hermes skills install official/research/scrapling 安裝
路徑optional-skills/research/scrapling
版本1.0.0
作者FEUAZUR
許可證MIT
標籤Web Scraping, Browser, Cloudflare, Stealth, Crawling, Spider
相關技能duckduckgo-search, domain-intel

參考:完整 SKILL.md

信息

以下是 Hermes 在觸發此技能時加載的完整技能定義。這是技能激活時代理所看到的指令。

Scrapling

Scrapling 是一個具有反機器人繞過、隱蔽瀏覽器自動化和蜘蛛框架的網頁抓取框架。它提供三種獲取策略(HTTP、動態 JS、隱蔽/Cloudflare)和完整的 CLI。

此技能僅用於教育和研究目的。 用戶必須遵守本地/國際數據抓取法律並尊重網站服務條款。

何時使用

  • 抓取靜態 HTML 頁面(比瀏覽器工具更快)
  • 抓取需要真實瀏覽器的 JS 渲染頁面
  • 繞過 Cloudflare Turnstile 或機器人檢測
  • 使用蜘蛛爬取多個頁面
  • 當內置的 web_extract 工具未返回所需數據時

安裝

pip install "scrapling[all]"
scrapling install

最小化安裝(僅 HTTP,無瀏覽器):

pip install scrapling

僅包含瀏覽器自動化:

pip install "scrapling[fetchers]"
scrapling install

快速參考

方法適用場景
HTTPFetcher / FetcherSession靜態頁面、API、快速批量請求
動態DynamicFetcher / DynamicSessionJS 渲染內容、單頁應用 (SPA)
隱蔽StealthyFetcher / StealthySessionCloudflare、受反機器人保護的網站
蜘蛛Spider跟隨鏈接的多頁面爬取

CLI 用法

提取靜態頁面

scrapling extract get 'https://example.com' output.md

使用 CSS 選擇器和瀏覽器偽裝:

scrapling extract get 'https://example.com' output.md \
--css-selector '.content' \
--impersonate 'chrome'

提取 JS 渲染頁面

scrapling extract fetch 'https://example.com' output.md \
--css-selector '.dynamic-content' \
--disable-resources \
--network-idle

提取受 Cloudflare 保護的頁面

scrapling extract stealthy-fetch 'https://protected-site.com' output.html \
--solve-cloudflare \
--block-webrtc \
--hide-canvas

POST 請求

scrapling extract post 'https://example.com/api' output.json \
--json '{"query": "search term"}'

輸出格式

輸出格式由文件擴展名決定:

  • .html -- 原始 HTML
  • .md -- 轉換為 Markdown
  • .txt -- 純文本
  • .json / .jsonl -- JSON

Python:HTTP 抓取

單次請求

from scrapling.fetchers import Fetcher

page = Fetcher.get('https://quotes.toscrape.com/')
quotes = page.css('.quote .text::text').getall()
for q in quotes:
print(q)

會話(持久化 Cookie)

from scrapling.fetchers import FetcherSession

with FetcherSession(impersonate='chrome') as session:
page = session.get('https://example.com/', stealthy_headers=True)
links = page.css('a::attr(href)').getall()
for link in links[:5]:
sub = session.get(link)
print(sub.css('h1::text').get())

POST / PUT / DELETE

page = Fetcher.post('https://api.example.com/data', json={"key": "value"})
page = Fetcher.put('https://api.example.com/item/1', data={"name": "updated"})
page = Fetcher.delete('https://api.example.com/item/1')

使用代理

page = Fetcher.get('https://example.com', proxy='http://user:pass@proxy:8080')

Python:動態頁面(JS 渲染)

對於需要執行 JavaScript 的頁面(SPA、懶加載內容):

from scrapling.fetchers import DynamicFetcher

page = DynamicFetcher.fetch('https://example.com', headless=True)
data = page.css('.js-loaded-content::text').getall()

等待特定元素

page = DynamicFetcher.fetch(
'https://example.com',
wait_selector=('.results', 'visible'),
network_idle=True,
)

禁用資源以提高速度

阻止字體、圖片、媒體、樣式表(速度提升約 25%):

from scrapling.fetchers import DynamicSession

with DynamicSession(headless=True, disable_resources=True, network_idle=True) as session:
page = session.fetch('https://example.com')
items = page.css('.item::text').getall()

自定義頁面自動化

from playwright.sync_api import Page
from scrapling.fetchers import DynamicFetcher

def scroll_and_click(page: Page):
page.mouse.wheel(0, 3000)
page.wait_for_timeout(1000)
page.click('button.load-more')
page.wait_for_selector('.extra-results')

page = DynamicFetcher.fetch('https://example.com', page_action=scroll_and_click)
results = page.css('.extra-results .item::text').getall()

Python:隱蔽模式(反機器人繞過)

對於受 Cloudflare 保護或具有強指紋識別的網站:

from scrapling.fetchers import StealthyFetcher

page = StealthyFetcher.fetch(
'https://protected-site.com',
headless=True,
solve_cloudflare=True,
block_webrtc=True,
hide_canvas=True,
)
content = page.css('.protected-content::text').getall()

隱蔽會話

from scrapling.fetchers import StealthySession

with StealthySession(headless=True, solve_cloudflare=True) as session:
page1 = session.fetch('https://protected-site.com/page1')
page2 = session.fetch('https://protected-site.com/page2')

元素選擇

所有獲取器都返回一個具有以下方法的 Selector 對象:

CSS 選擇器

page.css('h1::text').get()              # First h1 text
page.css('a::attr(href)').getall() # All link hrefs
page.css('.quote .text::text').getall() # Nested selection

XPath

page.xpath('//div[@class="content"]/text()').getall()
page.xpath('//a/@href').getall()

查找方法

page.find_all('div', class_='quote')       # By tag + attribute
page.find_by_text('Read more', tag='a') # By text content
page.find_by_regex(r'\$\d+\.\d{2}') # By regex pattern

相似元素

查找結構相似的元素(適用於產品列表等):

first_product = page.css('.product')[0]
all_similar = first_product.find_similar()
el = page.css('.target')[0]
el.parent # Parent element
el.children # Child elements
el.next_sibling # Next sibling
el.prev_sibling # Previous sibling

Python:蜘蛛框架

用於跟隨鏈接的多頁面爬取:

from scrapling.spiders import Spider, Request, Response

class QuotesSpider(Spider):
name = "quotes"
start_urls = ["https://quotes.toscrape.com/"]
concurrent_requests = 10
download_delay = 1

async def parse(self, response: Response):
for quote in response.css('.quote'):
yield {
"text": quote.css('.text::text').get(),
"author": quote.css('.author::text').get(),
"tags": quote.css('.tag::text').getall(),
}

next_page = response.css('.next a::attr(href)').get()
if next_page:
yield response.follow(next_page)

result = QuotesSpider().start()
print(f"Scraped {len(result.items)} quotes")
result.items.to_json("quotes.json")

多會話蜘蛛

將請求路由到不同類型的獲取器:

from scrapling.fetchers import FetcherSession, AsyncStealthySession

class SmartSpider(Spider):
name = "smart"
start_urls = ["https://example.com/"]

def configure_sessions(self, manager):
manager.add("fast", FetcherSession(impersonate="chrome"))
manager.add("stealth", AsyncStealthySession(headless=True), lazy=True)

async def parse(self, response: Response):
for link in response.css('a::attr(href)').getall():
if "protected" in link:
yield Request(link, sid="stealth")
else:
yield Request(link, sid="fast", callback=self.parse)

暫停/恢復爬取

spider = QuotesSpider(crawldir="./crawl_checkpoint")
spider.start() # Ctrl+C to pause, re-run to resume from checkpoint

常見陷阱

  • 需要安裝瀏覽器:pip 安裝後運行 scrapling install -- 否則 DynamicFetcherStealthyFetcher 將會失敗
  • 超時:DynamicFetcher/StealthyFetcher 的超時單位為毫秒(默認 30000),Fetcher 的超時單位為
  • Cloudflare 繞過solve_cloudflare=True 會增加 5-15 秒的獲取時間 -- 僅在需要時啟用
  • 資源使用:StealthyFetcher 運行真實瀏覽器 -- 限制併發使用
  • 法律合規:抓取前務必檢查 robots.txt 和網站服務條款。此庫僅用於教育和研究目的
  • Python 版本:需要 Python 3.10+