Maison > développement back-end > Tutoriel Python > Analyse Amazon à un niveau facile et tout seul

Analyse Amazon à un niveau facile et tout seul

PHPz
Libérer: 2024-08-31 06:04:33
original
1175 Les gens l'ont consulté

Je suis tombé sur un script sur Internet qui permet d'analyser les fiches produits d'Amazon. Et j'avais juste besoin d'une solution à un problème comme celui-là.

Je me suis creusé la tête en cherchant un moyen d'analyser les fiches produits d'Amazon. Le problème est qu'Amazon utilise différentes options de conception pour différentes sorties, en particulier – si vous devez analyser les cartes avec la requête de recherche « sacs » – les cartes seront disposées verticalement, comme j'en ai besoin, mais si vous prenez, par exemple , "t-shirts" – alors les cartes seront disposées horizontalement, et de cette manière le script tombe dans une erreur, il parvient à ouvrir la page, mais ne veut pas faire défiler.

Amazon parsing on easy level and all by yourself

De plus, après avoir lu divers articles dans lesquels les utilisateurs se demandent comment contourner le captcha sur Amazon, j'ai mis à jour le script et il peut désormais contourner le captcha s'il se produit (il fonctionne avec 2captcha). Le script vérifie la présence d'un captcha sur la page après chaque chargement d'une nouvelle page, et si le captcha se produit, il envoie une requête au serveur 2capcha, et après avoir reçu la solution, le remplace et continue de fonctionner.

Cependant, comment contourner le captcha n'est pas le problème le plus difficile, car c'est une tâche triviale de nos jours. La question la plus urgente est de savoir comment faire fonctionner le script non seulement avec la disposition verticale des fiches produits, mais aussi avec la disposition horizontale.

Ci-dessous, je vais décrire en détail ce que le script comprend, démontrer son travail et si vous pouvez aider à résoudre le problème, si vous savez quoi ajouter (modifier) ​​dans le script pour qu'il fonctionne sur une configuration horizontale des cartes, Je vous en serai reconnaissant.

Et pour l'instant, le script peut aider quelqu'un au moins dans ses fonctionnalités limitées.

Alors, démontons le script morceau par morceau !

Préparation

Tout d'abord, le script importe les modules nécessaires à la réalisation de la tâche

à partir du pilote Web d'importation de sélénium
à partir de selenium.webdriver.common.keys importer des clés
à partir de selenium.webdriver.common.action_chains, importez ActionChains
depuis selenium.webdriver.support.ui importer WebDriverWait
à partir de selenium.webdriver.support, importez les conditions_attendues en tant que EC
importer csv
importer un système d'exploitation
à partir du temps importer le sommeil
demandes d'importation

Démontons-le en plusieurs parties :

à partir du pilote Web d'importation de sélénium

Cela importe la classe webdriver, qui vous permet de contrôler le navigateur (dans mon cas Firefox) via le script

depuis selenium.webdriver.common.by import By

Cela importe la classe By, avec laquelle le script recherchera les éléments à analyser par XPath (il peut rechercher d'autres attributs, mais dans ce cas, XPath sera utilisé)

à partir de selenium.webdriver.common.keys importer des clés

Cela importe la classe Keys, qui sera utilisée pour simuler les frappes au clavier, dans le cas de ce script, il fera défiler la page vers le bas Keys.PAGE_DOWN

depuis selenium.webdriver.common.action_chains importez ActionChains

Cela importe la classe ActionChains pour créer des actions séquentielles complexes, dans notre cas – en cliquant sur le bouton PAGE_DOWN et en attendant que tous les éléments de la page se chargent (puisque sur Amazon, les cartes sont chargées au fur et à mesure qu'elles défilent)

depuis selenium.webdriver.support.ui importez WebDriverWait

Cela importe la classe WebDriverWait, qui attend que l'information que nous recherchons soit chargée, par exemple une description de produit, que nous rechercherons par Xpath

à partir de selenium.webdriver.support, importez les conditions_attendues en tant que EC

Cela importe la classe Expected_conditions (en abrégé EC) qui fonctionne en conjonction avec la classe précédente et indique à WebDriverWait quelle condition spécifique il doit attendre. Cela augmente la fiabilité du script afin qu'il ne commence pas à interagir avec le contenu encore déchargé.

importer csv

Cela importe le module csv pour travailler avec les fichiers csv.

importer le système d'exploitation

Cela importe le module os pour fonctionner avec le système d'exploitation (création de répertoires, vérification de la présence de fichiers, etc.).

à partir du temps d'importation du sommeil

Nous importons la fonction sleep – c'est la fonction qui mettra le script en pause pendant une durée précise (dans mon cas, 2 secondes, mais vous pouvez en définir plus) afin que les éléments se chargent pendant le défilement.

demandes d'importation

Cela importe la bibliothèque de requêtes pour l'envoi de requêtes HTTP, pour interagir avec le service de reconnaissance 2captcha.

Configuration

Une fois tout importé, le script commence à configurer le navigateur pour le travail, notamment :

Installation de la clé API pour accéder au service 2captcha

# Clé API pour 2Captcha
API_KEY =

Le script contient un agent utilisateur (il peut bien sûr être modifié), qui est installé pour le navigateur. Après cela, le navigateur démarre avec les paramètres spécifiés.

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

options = webdriver.FirefoxOptions()
options.add_argument(f"user-agent={user_agent}")

driver = webdriver.Firefox(options=options)
`

Vient ensuite le module de solution captcha. C’est exactement l’endroit que recherchent les utilisateurs lorsqu’ils cherchent comment résoudre un captcha. Nous n'analyserons pas ce morceau de code avant longtemps, car il n'a posé aucun problème particulier.

En bref, le script, après chaque chargement de page, vérifie la présence d'un captcha sur la page et s'il l'y trouve, le résout en l'envoyant au serveur 2captcha. S'il n'y a pas de captcha, l'exécution continue simplement.

`def solve_captcha(pilote) :
# Vérifier la présence d'un captcha sur la page
essayez :
captcha_element = driver.find_element(By.CLASS_NAME, 'g-recaptcha')
si captcha_element :
print("Captcha détecté. Résolution...")
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)
Copier après la connexion
Copier après la connexion


Analyse
Vient ensuite une section du code chargée de trier les pages, de les charger et de les faire défiler

essayez :
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)
Copier après la connexion

`

L'élément suivant est la collecte de données sur les produits. La partie la plus importante. Dans cette partie, le script examine la page chargée et récupère les données qui y sont spécifiées. Dans notre cas, il s'agit du nom du produit, du nombre d'avis, du prix, de l'URL, de la note du produit.

`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"]')

    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]
Copier après la connexion

`

Ensuite, les données spécifiées sont téléchargées dans un dossier (un fichier csv est créé pour chaque page, qui est enregistré dans le dossier des fichiers de sortie). Si le dossier est manquant, le script le crée.

`output_directory = "fichiers de sortie"
sinon 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])
Copier après la connexion

`

Et la dernière étape est l'achèvement des travaux et la libération des ressources.

enfin :
driver.quit()

Le scénario complet

`à partir du pilote Web d'importation de sélénium
à partir de selenium.webdriver.common.by import By
à partir de selenium.webdriver.common.keys importer des clés
à partir de selenium.webdriver.common.action_chains, importez ActionChains
depuis selenium.webdriver.support.ui importer WebDriverWait
à partir de selenium.webdriver.support, importez les conditions_attendues en tant que EC
importer csv
importer un système d'exploitation
à partir du temps importer le sommeil
demandes d'importation

Clé API pour 2Captcha

API_KEY = "Votre clé API"

Définir un agent utilisateur personnalisé pour imiter un vrai navigateur

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

options = webdriver.FirefoxOptions()
options.add_argument(f"user-agent={user_agent}")

driver = webdriver.Firefox(options=options)

def solve_captcha (pilote) :
# Vérifier la présence d'un captcha sur la page
essayez :
captcha_element = driver.find_element(By.CLASS_NAME, 'g-recaptcha')
si captcha_element :
print("Captcha détecté. Résolution...")
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)
Copier après la connexion
Copier après la connexion

essayez :
# URL de la page de démarrage
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])
Copier après la connexion

enfin :
driver.quit()

`

De cette façon, le script fonctionne sans erreur, mais uniquement pour les fiches produits verticales. Voici un exemple du fonctionnement du script.

Je serai ravi d'en discuter dans les commentaires si vous avez quelque chose à dire à ce sujet.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal