PythonでのWebスクレイピングの現状の問題点と間違いとそれを解決するコツ!

王林
リリース: 2024-08-23 06:04:31
オリジナル
936 人が閲覧しました

導入

こんにちは!私は Max です。ウクライナ出身の Python 開発者で、Web スクレイピング、データ分析、処理の専門知識を持つ開発者です。

私の Web スクレイピングへの取り組みは、2016 年に小さな会社の潜在顧客発掘の課題を解決していたときに始まりました。最初は、Import.io やmono Labs などの既製のソリューションを使用していました。ただし、ブロック、不正確なデータ抽出、パフォーマンスの問題などの制限がすぐに発生しました。これが私に Python を学ぶきっかけとなりました。当時はリクエストと lxml/Beautifulsoup だけでほとんどの Web サイトからデータを抽出できた栄光の時代でした。スレッドの操作方法を知っていたなら、あなたはすでに尊敬される専門家です :)

私たちのコミュニティ メンバーの 1 人が、Crawlee Blog への寄稿としてこのブログを書きました。このようなブログを Crawlee Blog に投稿したい場合は、Discord チャンネルまでご連絡ください。

クローリー&アピファイ

これは、Apify と Crawlee の公式開発者コミュニティです。 |会員数8318名

Current problems and mistakes of web scraping in Python and tricks to solve them! discord.com

私はフリーランサーとして、長年にわたって製品向けの小規模なソリューションと大規模で複雑なデータ マイニング システムを構築してきました。

今日は、2024 年の Python を使用した Web スクレイピングの現実について説明したいと思います。私が時々目にする間違いと遭遇する可能性のある問題を検討し、それらのいくつかに対する解決策を提供します。

始めましょう。

リクエストと美しいスープを受け取るだけで、たくさんのお金を稼ぎ始めることができます...

いいえ、これはそのような記事ではありません。

1. 「サーバーから 200 の応答を受け取りましたが、これは判読できない文字セットです。」

はい、驚くかもしれません。しかし、私は顧客や開発者からこのメッセージを 6 年前、4 年前、そして 2024 年にも見てきました。私はほんの数か月前に Reddit でこの問題に関する投稿を読みました。

簡単なコード例を見てみましょう。これは、クリーン インストールで拡張機能なしのリクエスト、httpx、および aiohttp で機能します。

import httpx

url = 'https://www.wayfair.com/'

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Connection": "keep-alive",
}

response = httpx.get(url, headers=headers)

print(response.content[:10])
ログイン後にコピー

印刷結果は次のようになります:

b'\x83\x0c\x00\x00\xc4\r\x8e4\x82\x8a'
ログイン後にコピー

これはエラーではありません。完全に有効なサーバー応答です。何らかの方法でエンコードされています。

答えは Accept-Encoding ヘッダーにあります。上の例では、ブラウザからコピーしただけなので、ブラウザがサポートするすべての圧縮方法 (「gzip、deflate、br、zstd」) がリストされています。 Wayfair バックエンドは、「br」 (Brotli) による圧縮をサポートしており、これを最も効率的な方法として使用します。

これは、上記のライブラリのいずれにも、標準の依存関係の中に Brotli 依存関係がない場合に発生する可能性があります。ただし、Brotli がすでにインストールされている場合、これらはすべてこの形式からの解凍をサポートしています。

したがって、適切なライブラリをインストールするだけで十分です。

pip install Brotli
ログイン後にコピー

これにより、印刷結果を取得できるようになります:

b'<!DOCTYPE '
ログイン後にコピー

拡張機能を使用してインストールを実行すると、aiohttp と httpx で同じ結果が得られます。

pip install aiohttp[speedups]
pip install httpx[brotli]
ログイン後にコピー

ところで、brotli の依存関係を追加したのが、私の crawee-python への最初の貢献でした。彼らは httpx をベース HTTP クライアントとして使用します。

少し前に、サポートされる新しいデータ圧縮形式 zstd が登場したことにもお気づきかもしれません。これを使用するバックエンドはまだ見たことがありませんが、httpx は 0.28.0 以降のバージョンで解凍をサポートする予定です。私はすでにプロジェクトでサーバー応答ダンプを圧縮するためにこれを使用しています。 aiofile を使用した非同期ソリューションでは驚くべき効率性を示します。

私がこれまでに見たこの状況に対する最も一般的な解決策は、開発者が単純に Accept-Encoding ヘッダーの使用を停止し、サーバーから非圧縮の応答を取得することです。なぜそれが悪いのでしょうか? Wayfair のメイン ページは、非圧縮で約 1 メガバイト、圧縮すると約 0.165 メガバイトかかります。

したがって、このヘッダーがない場合は次のようになります:

  • インターネット帯域幅の負荷が増加します。
  • トラフィックのあるプロキシを使用すると、各リクエストのコストが増加します。
  • サーバーのインターネット帯域幅の負荷が増加します。
  • どのブラウザも圧縮を使用しているため、あなたはスクレーパーであることを明らかにしていることになります。

しかし、問題はそれよりももう少し深いと思います。多くの Web スクレイピング開発者は、使用するヘッダーが何をするのかを理解していません。したがって、これがあなたに当てはまる場合は、次のプロジェクトに取り組むときに、これらのことを読んでください。驚かれるかもしれません。

2. 「シークレットブラウザと同じようにヘッダーを使用していますが、403 応答が返されます。」こちらがジョンです...つまり、Cloudflareです

はい、その通りです。 2023 年には、ChatGPT のような大規模言語モデルだけでなく、Cloudflare の保護も改善されました。

長い間 Web をスクレイピングしている人は、「まあ、DataDome、PerimeterX、InCapsula などはすでに扱ったことがある」と言うかもしれません。

しかし、Cloudflare はゲームのルールを変えました。これは世界最大の CDN プロバイダーの 1 つであり、膨大な数のサイトにサービスを提供しています。したがって、そのサービスは参入障壁がかなり低く、多くのサイトで利用できます。これは、サイトをスクレイピングから保護するために意図的に実装された前述のテクノロジーとは根本的に異なります。

Cloudflare は、「リクエストと beautifulsoup を使用して Web スクレイピングを行う方法」に関する別のコースを読み始めたときにすぐに閉じることができる理由です。なぜなら、あなたが学んだ内容が「まともな」ウェブサイトでは機能しない可能性が非常に高いからです。

別の簡単なコード例を見てみましょう:

from httpx import Client

client = Client(http2=True)

url = 'https://www.g2.com/'

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Connection": "keep-alive",
}

response = client.get(url, headers=headers)

print(response)
ログイン後にコピー

もちろん、応答は 403 になります。

curl を使用するとどうなるでしょうか?

curl -XGET -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Connection: keep-alive' 'https://www.g2.com/' -s -o /dev/null -w "%{http_code}\n"
ログイン後にコピー

403 とも呼ばれます。

なぜこのようなことが起こっているのですか?

Cloudflareは開発者の間で人気のある多くのHTTPクライアントのTLSフィンガープリントを使用するため、サイト管理者はこれらのフィンガープリントに基づいてCloudflareがクライアントをどの程度積極的にブロックするかをカスタマイズすることもできます。

curl の場合、次のように解決できます。

curl -XGET -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Connection: keep-alive' 'https://www.g2.com/' --tlsv1.3 -s -o /dev/null -w "%{http_code}\n"
ログイン後にコピー

You might expect me to write here an equally elegant solution for httpx, but no. About six months ago, you could do the "dirty trick" and change the basic httpcore parameters that it passes to h2, which are responsible for the HTTP2 handshake. But now, as I'm writing this article, that doesn't work anymore.

There are different approaches to getting around this. But let's solve it by manipulating TLS.

The bad news is that all the Python clients I know of use the ssl library to handle TLS. And it doesn't give you the ability to manipulate TLS subtly.

The good news is that the Python community is great and implements solutions that exist in other programming languages.

The first way to solve this problem is to use tls-client

This Python wrapper around the Golang library provides an API similar to requests.

pip install tls-client
ログイン後にコピー
from tls_client import Session

client = Session(client_identifier="firefox_120")

url = 'https://www.g2.com/'

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Connection": "keep-alive",
}

response = client.get(url, headers=headers)

print(response)
ログイン後にコピー

The tls_client supports TLS presets for popular browsers, the relevance of which is maintained by developers. To use this, you must pass the necessary client_identifier. However, the library also allows for subtle manual manipulation of TLS.

The second way to solve this problem is to use curl_cffi

This wrapper around the C library patches curl and provides an API similar to requests.

pip install curl_cffi
ログイン後にコピー
from curl_cffi import requests

url = 'https://www.g2.com/'

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Connection": "keep-alive",
}

response = requests.get(url, headers=headers, impersonate="chrome124")

print(response)
ログイン後にコピー

curl_cffi also provides TLS presets for some browsers, which are specified via the impersonate parameter. It also provides options for subtle manual manipulation of TLS.

I think someone just said, "They're literally doing the same thing." That's right, and they're both still very raw.

Let's do some simple comparisons:

Feature tls_client curl_cffi
TLS preset + +
TLS manual + +
async support - +
big company support - +
number of contributors - +

この比較では、明らかに、curl_cffi が勝ちます。しかし、アクティブなユーザーとして、時々、対処方法がわからない非常に奇妙なエラーが発生することがあると言わざるを得ません。正直に言うと、今のところ、どちらもかなり生々しいものです。

この問題を解決する他のライブラリがすぐに見つかると思います。

Scrapy はどうなの?と思う人もいるかもしれません。正直に言うと、私は彼らの最新情報をあまりチェックしていません。しかし、Zyte が TLS フィンガープリンティングを回避するために何かを行っているという話は聞いたことがありません。したがって、そのままでは Scrapy もブロックされますが、Scrapy Spider でのcurl_cffiの使用を妨げるものは何もありません。

3. ヘッドレスブラウザとCloudflare Turnstileはどうですか?

はい、ヘッドレス ブラウザを使用する必要がある場合があります。正直に言いますが、私の観点からすると、明らかに必要ない場合でも、それらは頻繁に使用されすぎます。

Cloudflare の人々は、首なしの状況であっても、Cloudflare Turnstile と呼ばれるモンスターを作成することで、平均的な Web スクレイパーの生活を困難にすることに成功しました。

さまざまなツールをテストするには、このデモ ページを使用できます。

ライブラリがブラウザで動作するかどうかを簡単にテストするには、通常の非ヘッドレス モードを確認することから始める必要があります。自動化を使用する必要さえありません。目的のライブラリを使用してサイトを開いて手動で操作するだけです。

このためにチェックする価値のあるライブラリは何ですか?

候補者 #1 劇作家 + 劇作家ステルス

ブロックされるため、キャプチャを解決できなくなります。

Playwright は、ブラウザ自動化のための優れたライブラリです。ただし、開発者は、Web スクレイピング ツールとして開発する予定はないと明言しています。

そして、この問題を効果的に解決する Python プロジェクトについては聞いたことがありません。

候補 #2 undetected_chromedriver

ブロックされるため、キャプチャを解決できなくなります。

これは、Python でヘッドレス ブラウザを操作するための非常に一般的なライブラリであり、場合によっては Cloudflare Turnstile をバイパスできます。しかし、対象の Web サイトではブロックされています。また、私のプロジェクトでは、Cloudflare が undetected_chromedriver をブロックした他のケースに少なくとも 2 件遭遇しました。

一般に、undetected_chromedriver は、特に内部で古き良き Selenium を使用しているため、プロジェクトに適したライブラリです。

候補者その3 ボタサウルスドライバー

クリックした後にキャプチャを通過できるようになります。

開発者がどのようにしてこれを実現したのかはわかりませんが、機能します。その主な特徴は、Webスクレイピング専用に開発されたことです。また、操作できる高レベルのライブラリである botasaurus もあります。

欠点としては、これまでのところ、かなり未加工であり、botasaurus-driver にはドキュメントがなく、操作するのがかなり難しい API があることです。

要約すると、ヘッドレス ブラウジングのメイン ライブラリは undetected_chromedriver になる可能性が高くなります。ただし、特に困難なケースでは、ボタサウルスの使用が必要になる場合があります。

4. フレームワークについてはどうですか?

高レベルのフレームワークは、ビジネス ロジックに集中できるようにすることで開発をスピードアップし、容易にするように設計されていますが、多くの場合、柔軟性と制御の面で代償を支払います。

それでは、2024 年の Web スクレイピングのフレームワークは何でしょうか?

スクレイピー

Scrapy に触れずに Python Web スクレイピング フレームワークについて語ることはできません。 Scrapinghub (現 Zyte) は 2008 年に初めてリリースしました。16 年間、開発会社がビジネス ソリューションを構築するためのオープンソース ライブラリとして開発されてきました。

Scrapy の利点については、別の記事を書くこともできます。しかし、私はそれら 2 つを強調します:

  • 長年にわたってリリースされてきた膨大な量のチュートリアル
  • ミドルウェア ライブラリはコミュニティによって作成され、その機能を拡張しています。たとえば、scrapy-playwright.

しかし、欠点は何でしょうか?

近年、Zyte は独自のプラットフォームの開発に重点を置いています。 Scrapy はほとんどの場合、修正のみを取得します。

  • アンチスクレイピングシステムをバイパスするための開発の欠如。自分で実装する必要がありますが、では、なぜフレームワークが必要なのでしょうか?
  • Scrapy は元々、非同期フレームワーク Twisted を使用して開発されました。 asyncio の部分的なサポートはバージョン 2.0 でのみ追加されました。ソース コードを見ると、この目的のために追加されたいくつかの回避策に気づくかもしれません。

したがって、Scrapy は、Web スクレイピングから保護されていないサイトにとって、優れた実証済みのソリューションです。スクレイピング防止対策を回避するには、必要なソリューションを開発してフレームワークに追加する必要があります。

ボタサウルス

botasaurus-driver に基づいて構築された、ブラウザ自動化を使用した Web スクレイピング用の新しいフレームワーク。最初のコミットは 2023 年 5 月 9 日に行われました。

その利点から始めましょう:

  • botasaurus ドライバーを使用して、Claudflare 保護だけでなく他の多くの保護もバイパスできます。
  • すぐに始めるための優れたドキュメント

欠点は次のとおりです:

  • ブラウザ自動化のみ。HTTP クライアントを対象としていません。
  • botasaurus ドライバーとの密結合。将来的により良いものが登場したとしても、簡単に置き換えることはできません。
  • 非同期はなく、マルチスレッドのみです。
  • 現時点ではかなり未加工な状態であり、安定した動作のためにはまだ修正が必要です。
  • 現時点で利用できるトレーニング資料はほとんどありません。

これは、ブラウザ自動化に基づいた Web スクレイパーを迅速に構築するための優れたフレームワークです。柔軟性と HTTP クライアントのサポートが欠けていますが、これは私のようなユーザーにとって重要です。

Python のクローリー

Python エコシステムにおける Web スクレイピング用の新しいフレームワーク。最初のコミットは 2024 年 1 月 10 日に行われ、メディア スペースでのリリースは 2024 年 7 月 5 日に行われました。

Current problems and mistakes of web scraping in Python and tricks to solve them! アピファイ / クローリーパイソン

Crawlee - 信頼性の高いクローラを構築するための Python 用の Web スクレイピングおよびブラウザ自動化ライブラリ。 AI、LLM、RAG、または GPT のデータを抽出します。 HTML、PDF、JPG、PNG、その他のファイルを Web サイトからダウンロードします。 BeautifulSoup、Playwright、生の HTTP で動作します。ヘッドフルモードとヘッドレスモードの両方。プロキシローテーションあり。

Current problems and mistakes of web scraping in Python and tricks to solve them!
Webスクレイピングとブラウザ自動化ライブラリ

Current problems and mistakes of web scraping in Python and tricks to solve them! Current problems and mistakes of web scraping in Python and tricks to solve them! Current problems and mistakes of web scraping in Python and tricks to solve them! Current problems and mistakes of web scraping in Python and tricks to solve them!

Crawlee はクローリングとスクレイピングをエンドツーエンドでカバーし、信頼性の高いスクレーパーの構築を支援します。早いです。

? Crawlee for Python は早期採用者に公開されています!

あなたのクローラーはほとんど人間のように見え、デフォルト設定であっても最新のボット保護のレーダーの下を飛行します。 Crawlee は、技術的な詳細を気にすることなく、Web をクロールしてリンクを探し、データを収集し、機械可読形式で永続的に保存するためのツールを提供します。また、豊富な構成オプションのおかげで、デフォルト設定では不十分な場合でも、プロジェクトのニーズに合わせて Crawlee のほぼすべての側面を調整できます。

? Crawlee プロジェクト Web サイトで完全なドキュメント、ガイド、例を表示します ?

Crawlee の TypeScript 実装もあります。これを探索してプロジェクトに活用できます。詳細については、GitHub 上の Crawlee for JS/TS の GitHub リポジトリにアクセスしてください。

インストール

私たちは…


GitHub で表示


これは Apify によって開発され、有名な JS フレームワーク Crolee を Python に適応させたもので、2019 年 7 月 9 日に初めてリリースされました。

これは市場ではまったく新しいソリューションであるため、現在、設計と開発が活発な段階にあります。コミュニティもその開発に積極的に参加しています。したがって、curl_cffi の使用がすでに議論されていることがわかります。独自の Rust ベースのクライアントを作成する可能性については、以前に説明しました。会社がこのアイデアを放棄しないことを願っています。

クローリーチームより:
「そうですね、確かに私たちは今後何年にもわたって Crawlee for Python を改善し続けます。」

個人的には、Python 用の HTTP クライアントが大手企業によって開発および保守されることを望んでいます。そして、Rust は Python のライブラリ言語として非常に優れています。少なくとも Ruff と Pydantic v2 は覚えておきましょう。

利点:

このフレームワークは、Web スクレイピング市場で確立された企業によって開発され、この分野で十分に開発された専門知識を持っています。

  • ブラウザ自動化と HTTP クライアントの両方をサポートします。
  • asyncio に基づいた完全な非同期。
  • 活発な開発段階とメディア活動。開発者はコミュニティの意見に耳を傾けるので、このフェーズではコミュニティの意見が非常に重要です。

別の話になりますが、これは非常に優れたモジュラー アーキテクチャを備えています。開発者が複数の HTTP クライアントを切り替える機能を導入すれば、開発チームによる簡単な実装で、使用するテクノロジを簡単に変更できる、かなり柔軟なフレームワークが得られます。

欠陥:

  • フレームワークは新しいです。現時点で利用できるトレーニング資料はほとんどありません。
  • 現時点ではかなり未加工な状態であり、安定した動作のための修正と、設定に便利なインターフェースがまだ必要です。 - 今のところ、セッションとプロキシを変更する以外に、アンチスクレイピング システムをバイパスする手段は実装されていません。しかし、それらは議論されています。

私は、crawlee-python がどのように成功するかは主にコミュニティに依存すると信じています。チュートリアルの数が少ないため、初心者には向きません。ただし、経験豊富な開発者は、Scrapy の代わりに Scrapy を試してみることにするかもしれません。

長期的には、Scrapy や Botasaurus よりも良い解決策になるかもしれません。 HTTP クライアントを操作し、すぐに使えるブラウザを自動化し、ブラウザを素早く切り替えるための柔軟なツールがすでに提供されています。ただし、スクレイピング保護をバイパスするツールが不足しているため、将来のその実装がフレームワークを選択する際の決定要因となる可能性があります。

結論

ここまで読んでくださった方は、興味深く、役に立ったと思います :)

業界は変化し、新たな課題をもたらしており、Web スクレイピングに専門的に携わっている場合は、状況を注意深く監視する必要があります。他の分野では、時代遅れのテクノロジーを使用して製品を作る開発者のままになるでしょう。しかし、最新の Web スクレイピングでは、まったく機能しない Web スクレイパーを作成する開発者になります。

また、あなたは大規模な Python コミュニティの一員であることを忘れないでください。あなたの知識は、私たち全員のために物事を実現するツールの開発に役立つ可能性があります。ご覧のとおり、必要なツールの多くは文字通り現在構築されています。

コメントを楽しみに読ませていただきます。また、Web スクレイピングの専門家が必要な場合、または単に記事について議論したい場合は、Github、Linkedin、Apify、Upwork、Contra のプラットフォームで私を見つけることができます。

ご清聴ありがとうございます:)

以上がPythonでのWebスクレイピングの現状の問題点と間違いとそれを解決するコツ!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!