ホームページ  >  記事  >  バックエンド開発  >  簡単なレベルですべて自分で Amazon を解析する

簡単なレベルですべて自分で Amazon を解析する

PHPz
PHPzオリジナル
2024-08-31 06:04:331153ブラウズ

インターネット上で、Amazon の商品カードを解析できるスクリプトを見つけました。そして、そのような問題に対する解決策が必要だったのです。

Amazon の商品カードを解析する方法を探しているときに、私は頭を悩ませました。問題は、Amazon が出力ごとに異なるデザイン オプションを使用していることです。特に、検索クエリ「bags」でカードを解析する必要がある場合、必要に応じてカードが垂直に配置されますが、たとえば次のようになります。 、「T シャツ」 – この場合、カードは水平に配置され、スクリプトはエラーに陥り、ページを開くことはできますが、スクロールしたくありません。

Amazon parsing on easy level and all by yourself

さらに、Amazon でキャプチャをバイパスする方法についてユーザーが困惑しているさまざまな記事を読んだ後、スクリプトをアップグレードし、キャプチャが発生した場合にキャプチャをバイパスできるようになりました (2captcha で動作します)。スクリプトは、新しいページを読み込むたびにページ上にキャプチャが存在するかどうかをチェックし、キャプチャが発生した場合は 2capcha サーバーにリクエストを送信し、解決策を受信した後、それを置き換えて動作を継続します。

しかし、キャプチャを回避する方法は、今日では簡単な作業であるため、最も難しい問題ではありません。より差し迫った問題は、スクリプトを製品カードの垂直方向の配置だけでなく、水平方向の配置でも機能させるにはどうすればよいかということです。

以下では、スクリプトに含まれる内容とその動作を詳しく説明します。また、問題の解決に役立つかどうか、カードの水平方向のセットアップで機能するようにスクリプトに何を追加 (変更) すればよいかご存知の場合は、よろしくお願いします。

そして今のところ、このスクリプトは少なくともその限られた機能においては誰かを助けることができます。

それでは、スクリプトを部分的に分解してみましょう!

準備

まず、スクリプトはタスクを完了するために必要なモジュールをインポートします

Selenium インポート Web ドライバーから
from selenium.webdriver.common.keys import Keys
selenium.webdriver.common.action_chains から ActionChains をインポートします
selenium.webdriver.support.ui から import WebDriverWait
selenium.webdriver.support から、expected_conditions を EC
としてインポートします csv をインポート
OS をインポート
時間インポート睡眠から
インポートリクエスト

パーツに分けてみましょう:

Selenium インポート Web ドライバーから

これにより、スクリプトを通じてブラウザ (私の場合は Firefox) を制御できるようにする webdriver クラスがインポートされます

selenium.webdriver.common.by から import By

これは theBy クラスをインポートし、スクリプトはこのクラスを使用して XPath で解析する要素を検索します (他の属性も検索できますが、この場合は Xpath が使用されます)

selenium.webdriver.common.keys からキーをインポート

これは、キーストロークをシミュレートするために使用される Keys クラスをインポートします。このスクリプトの場合、ページを下にスクロールします Keys.PAGE_DOWN

selenium.webdriver.common.action_chains から ActionChains をインポートします

ActionChains クラスをインポートして、複雑な連続アクションを作成します。この例では、PAGE_DOWN ボタンをクリックし、ページ上のすべての要素が読み込まれるのを待ちます (Amazon カードはスクロール中に読み込まれるため)

selenium.webdriver.support.ui から WebDriverWait をインポート

これにより、WebDriverWait クラスがインポートされます。このクラスは、探している情報 (Xpath で検索する製品の説明など) が読み込まれるまで待機します

selenium.webdriver.support から、expected_conditions を EC としてインポートします

これは、前のクラスと連携して動作する Expected_conditions クラス (略称 EC) をインポートし、どの特定の条件を待つ必要があるかを WebDriverWait に指示します。これにより、スクリプトの信頼性が向上し、アンロードされたコンテンツとの対話が開始されなくなります。

CSV をインポート

これにより、csv ファイルを操作するために csv モジュールがインポートされます。

OS をインポート

これにより、オペレーティング システムと連携するために OS モジュールがインポートされます (ディレクトリの作成、ファイルの存在の確認など)。

時間インポートスリープから

スリープ関数をインポートします。これは、スクロール中に要素が読み込まれるように、スクリプトを特定の時間 (私の場合は 2 秒ですが、さらに設定できます) 一時停止する関数です。

インポートリクエスト

これは、2captcha 認識サービスと対話するために、HTTP リクエストを送信するためのリクエスト ライブラリをインポートします。

構成

すべてがインポートされた後、スクリプトは、特に次のような動作のためにブラウザーの構成を開始します。

2captcha サービスにアクセスするための API キーのインストール

# 2Captcha の API キー
API_KEY =

スクリプトには、ブラウザー用にインストールされるユーザー エージェント (もちろん変更可能) が含まれています。その後、指定した設定でブラウザが起動します。

`user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML、Gecko など) Chrome/91.0.4472.124 Safari/537.36"

オプション = webdriver.FirefoxOptions()
options.add_argument(f"user-agent={user_agent}")

ドライバー = webdriver.Firefox(options=options)
`

次に、キャプチャ ソリューション モジュールが登場します。これはまさに、ユーザーがキャプチャの解決方法を検索するときに探している場所です。特に問題がなかったので、このコードは長期間分析しません。

つまり、スクリプトは、各ページのロード後に、ページ上にキャプチャが存在するかどうかを確認し、キャプチャが見つかった場合は、2captcha サーバーに送信して問題を解決します。キャプチャがない場合は、さらに実行が続行されます。

`defsolve_captcha(ドライバー):
# ページにキャプチャが存在するかどうかを確認します
試してみてください:
captcha_element = driver.find_element(By.CLASS_NAME, 'g-recaptcha')
captcha_element の場合:
print("キャプチャが検出されました。解決中...")
site_key = captcha_element.get_attribute('data-sitekey')
current_url = driver.current_url

        # Send captcha request to 2Captcha
        captcha_id = requests.post(
            'http://2captcha.com/in.php', 
            data={
                'key': API_KEY, 
                'method': 'userrecaptcha', 
                'googlekey': site_key, 
                'pageurl': current_url
            }
        ).text.split('|')[1]

        # Wait for the captcha to be solved
        recaptcha_answer = ''
        while True:
            sleep(5)
            response = requests.get(f"http://2captcha.com/res.php?key={API_KEY}&action=get&id={captcha_id}")
            if response.text == 'CAPCHA_NOT_READY':
                continue
            if 'OK|' in response.text:
                recaptcha_answer = response.text.split('|')[1]
                break

        # Inject the captcha answer into the page
        driver.execute_script(f'document.getElementById("g-recaptcha-response").innerHTML = "{recaptcha_answer}";')
        driver.find_element(By.ID, 'submit').click()
        sleep(5)
        print("Captcha solved.")
except Exception as e:
    print("No captcha found or error occurred:", e)


解析中
次に、ページの並べ替え、読み込み、スクロールを担当するコードのセクションが続きます

試してみてください:
base_url = "https://www.amazon.in/s?k=bags"

for page_number in range(1, 10): 
    page_url = f"{base_url}&page={page_number}"

    driver.get(page_url)
    driver.implicitly_wait(10)

    solve_captcha(driver)

    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//span[@class="a-size-medium a-color-base a-text-normal"]')))

    for _ in range(5):  
        ActionChains(driver).send_keys(Keys.PAGE_DOWN).perform()
        sleep(2)

`

次の部分は製品データの収集です。最も重要な部分です。この部分では、スクリプトはロードされたページを調べ、そこから指定されたデータを取得します。私たちの場合、それは製品名、レビュー数、価格、URL、製品評価です。

`product_name_elements = driver.find_elements(By.XPATH, '//span[@class="a-size-medium a-color-base a-text-normal"]')
Rating_number_elements = driver.find_elements(By.XPATH, '//span[@class="a-size-base s-underline-text"]')
star_rated_elements = driver.find_elements(By.XPATH, '//span[@class="a-icon-alt"]')
Price_elements = driver.find_elements(By.XPATH, '//span[@class="a-price-whole"]')
product_urls = driver.find_elements(By.XPATH, '//a[@class="a-link-normal s-underline-text s-underline-link-text s-link-style a-text-normal"]')

    product_names = [element.text for element in product_name_elements]
    rating_numbers = [element.text for element in rating_number_elements]
    star_ratings = [element.get_attribute('innerHTML') for element in star_rating_elements]
    prices = [element.text for element in price_elements]
    urls = [element.get_attribute('href') for element in product_urls]

`

次に、指定したデータがフォルダーにアップロードされます (ページごとに csv ファイルが作成され、出力ファイルフォルダーに保存されます)。フォルダーが見つからない場合は、スクリプトによってフォルダーが作成されます。

` 出力ディレクトリ = "出力ファイル"
そうでない場合は、os.path.exists(output_directory):
os.makedirs(出力ディレクトリ)

    with open(os.path.join(output_directory, f'product_details_page_{page_number}.csv'), 'w', newline='', encoding='utf-8') as csvfile:
        csv_writer = csv.writer(csvfile)
        csv_writer.writerow(['Product Urls', 'Product Name', 'Product Price', 'Rating', 'Number of Reviews'])
        for url, name, price, star_rating, num_ratings in zip(urls, product_names, prices, star_ratings, rating_numbers):
            csv_writer.writerow([url, name, price, star_rating, num_ratings])

`

そして最後の段階は、作業の完了とリソースの解放です。

最後に:
driver.quit()

完全なスクリプト

`Selenium インポート Web ドライバーから
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
selenium.webdriver.common.action_chains から ActionChains をインポートします
selenium.webdriver.support.ui から import WebDriverWait
selenium.webdriver.support から、expected_conditions を EC
としてインポートします csv をインポート
OS をインポート
時間インポート睡眠から
インポートリクエスト

2Captcha の API キー

API_KEY = "あなたの API キー"

実際のブラウザを模倣するようにカスタム ユーザー エージェントを設定する

user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML、Gecko など) Chrome/91.0.4472.124 Safari/537.36"

オプション = webdriver.FirefoxOptions()
options.add_argument(f"user-agent={user_agent}")

ドライバー = webdriver.Firefox(options=options)

defsolve_captcha(ドライバー):
# ページにキャプチャが存在するかどうかを確認します
試してみてください:
captcha_element = driver.find_element(By.CLASS_NAME, 'g-recaptcha')
captcha_element の場合:
print("キャプチャが検出されました。解決中...")
site_key = captcha_element.get_attribute('data-sitekey')
current_url = driver.current_url

        # Send captcha request to 2Captcha
        captcha_id = requests.post(
            'http://2captcha.com/in.php', 
            data={
                'key': API_KEY, 
                'method': 'userrecaptcha', 
                'googlekey': site_key, 
                'pageurl': current_url
            }
        ).text.split('|')[1]

        # Wait for the captcha to be solved
        recaptcha_answer = ''
        while True:
            sleep(5)
            response = requests.get(f"http://2captcha.com/res.php?key={API_KEY}&action=get&id={captcha_id}")
            if response.text == 'CAPCHA_NOT_READY':
                continue
            if 'OK|' in response.text:
                recaptcha_answer = response.text.split('|')[1]
                break

        # Inject the captcha answer into the page
        driver.execute_script(f'document.getElementById("g-recaptcha-response").innerHTML = "{recaptcha_answer}";')
        driver.find_element(By.ID, 'submit').click()
        sleep(5)
        print("Captcha solved.")
except Exception as e:
    print("No captcha found or error occurred:", e)

試してください:
# 開始ページ URL
base_url = "https://www.amazon.in/s?k=bags"

for page_number in range(1, 2): 
    page_url = f"{base_url}&page={page_number}"

    driver.get(page_url)
    driver.implicitly_wait(10)

    # Attempt to solve captcha if detected
    solve_captcha(driver)

    # Explicit Wait
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//span[@class="a-size-medium a-color-base a-text-normal"]')))

    for _ in range(5):  
        ActionChains(driver).send_keys(Keys.PAGE_DOWN).perform()
        sleep(2)

    product_name_elements = driver.find_elements(By.XPATH, '//span[@class="a-size-medium a-color-base a-text-normal"]')
    rating_number_elements = driver.find_elements(By.XPATH, '//span[@class="a-size-base s-underline-text"]')
    star_rating_elements = driver.find_elements(By.XPATH, '//span[@class="a-icon-alt"]')
    price_elements = driver.find_elements(By.XPATH, '//span[@class="a-price-whole"]')
    product_urls = driver.find_elements(By.XPATH, '//a[@class="a-link-normal s-underline-text s-underline-link-text s-link-style a-text-normal"]')

    # Extract and print the text content of each product name, number of ratings, and star rating, urls
    product_names = [element.text for element in product_name_elements]
    rating_numbers = [element.text for element in rating_number_elements]
    star_ratings = [element.get_attribute('innerHTML') for element in star_rating_elements]
    prices = [element.text for element in price_elements]
    urls = [element.get_attribute('href') for element in product_urls]

    sleep(5)        
    output_directory = "output files"
    if not os.path.exists(output_directory):
        os.makedirs(output_directory)

    with open(os.path.join(output_directory, f'product_details_page_{page_number}.csv'), 'w', newline='', encoding='utf-8') as csvfile:
        csv_writer = csv.writer(csvfile)
        csv_writer.writerow(['Product Urls', 'Product Name', 'Product Price', 'Rating', 'Number of Reviews'])
        for url, name, price, star_rating, num_ratings in zip(urls, product_names, prices, star_ratings, rating_numbers):
            csv_writer.writerow([url, name, price, star_rating, num_ratings])

最後に:
driver.quit()

`

この方法では、スクリプトはエラーなしで動作しますが、垂直の製品カードに対してのみ機能します。以下に、スクリプトがどのように機能するかを示す例を示します。

それについて何かご意見がございましたら、喜んでコメント欄で議論させていただきます。

以上が簡単なレベルですべて自分で Amazon を解析するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。