[PYTHON] [Selenium] Aller à la page suivante sans appuyer sur Suivant

1. Contexte / objectif

Teratail qui est souvent pris en charge (https://teratail.com) Parfois, il y a un gars qui joue depuis des années sans qu'on lui réponde du tout. Je me demande ce qu'il y en a beaucoup en termes de catégories (tags) Je pense faire un bon grattage.

Ce que j'ai remarqué, c'est que la dernière page se termine toujours par 500. La même 500e page s'affiche même si vous appuyez sur le bouton "Suivant". C'est une boucle sans fin. Alors je vais gratter de manière à l'éviter.

2. Hypothèses

Cette fois, j'utiliserai du sélénium avec Python 3.7.

3. Flux

--Accédez à l'URL sans réponse "https://teratail.com/feed/not-answered/" --Recueillir toutes les balises sur chaque page --Ajouter "/ tag" dans href à la liste

4. Script entier

No_answered_Tags.py



def main():

    import pandas as pd
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException
    

    options = Options()
    options.add_argument('--headless')
    browser = webdriver.Chrome(executable_path='/Users/anatanonamae/Desktop/Tool/chromedriver', chrome_options=options)

    browser.implicitly_wait(3)

    #Accédez à la première page
    PAGE = 1
    InitURL= "https://teratail.com/search?tab=active&page=" + str(PAGE) + "&q=is%3Anot-answered"
    browser.get(InitURL)
    print("J'ai accédé à la première page")

    #Collecte d'informations sur chaque page
    TAG_DIC={}    
    while True:
        A_TAG = browser.find_elements_by_tag_name("a")#collecter une étiquette
        
        taglist=[]
        for TAG in A_TAG :
            HREF = TAG.get_attribute('href') #Recueillir href
              
            if "tags" in str(HREF):#Collecter des hrefs contenant des balises
                if not TAG.text:
                    continue                        
                else:
                     taglist.append(TAG.text)

        for tag in taglist:
            if tag in TAG_DIC:
                 TAG_DIC[tag] += 1
            else:
                TAG_DIC[tag] = 1
            
        NEXT_XPATH = browser.find_elements_by_xpath("//*[@id=\"mainContainer\"]/div[4]/div/p/a/span[contains(text(),\'Page suivante\')]")

        if NEXT_XPATH:#Ajouter une PAGE s'il y a une prochaine
            PAGE += 1

        else:
            print("Got tags at last page.")#Sinon, c'est fini
            break

        browser.get(URL)#Aller à la page suivante
        WebDriverWait(browser, 2).until(EC.presence_of_all_elements_located)
        print(browser.current_url)
        if browser.title == "Page non trouvée":
            print("Got tags at last page.")#Si une erreur se produit sur la page suivante, le processus se termine.
            break
 
    #Post-traitement: création d'une Dataframe
    df = pd.DataFrame([TAG_DIC.keys(),TAG_DIC.values()],index=None).T#Convertir en Dataframe
    df.rename(columns={0:"Tag",1:"Count"},inplace =True)#Renommer la colonne
    df.sort_values(by=['Count'],ascending=False,inplace =True)#Trier par ordre décroissant
    df.reset_index(drop=True,inplace=True)#Réaffecter l'index
        
    print(df)

if __name__ == "__main__":
    main()

5. Explication de chaque lieu

  1. Commencez par effectuer les réglages de base de Selenium.

selenium.py


    options = Options()#Paramètres des options de sélénium
    options.add_argument('--headless')#N'ouvre pas la fenêtre
    browser = webdriver.Chrome(executable_path='/Users/anatanonamae/Desktop/Tool/chromedriver', chrome_options=options)#Appel du pilote et options de paramétrage

    browser.implicitly_wait(3)#Réglage du temps d'attente
  1. Accédez à la première page

access.py


    #Accédez à la première page
    PAGE = 1
    InitURL= "https://teratail.com/search?tab=active&page=" + str(PAGE) + "&q=is%3Anot-answered"
    browser.get(InitURL)#Accès avec get
    print("J'ai accédé à la première page")#browser.current_Vous pouvez également afficher la page actuelle avec l'URL.
  1. Traitement en boucle Nous collecterons des balises sur chaque page. --A Collecter toutes les balises avec find_elements_by_tag_name --Sélectionnez ceux qui contiennent "tag" dans le href.

WebDriverWait (browser, 2) .until (EC.presence_of_all_elements_located) est le même usage que sleep mais plus puissant. Vous pouvez demander d'attendre que la page soit acquise correctement. Pour plus d'informations: https://qiita.com/uguisuheiankyo/items/cec03891a86dfda12c9a

loop.py


    #Collecte d'informations sur chaque page
    TAG_DIC={}    
    while True:
        A_TAG = browser.find_elements_by_tag_name("a")#collecter une étiquette
        
        taglist=[]
        for TAG in A_TAG :
            HREF = TAG.get_attribute('href') #Recueillir href
              
            if "tags" in str(HREF):#Collecter des hrefs contenant des balises
                if not TAG.text:#Ignorer si vide
                    continue                        
                else:
                     taglist.append(TAG.text)

        for tag in taglist:
            if tag in TAG_DIC:
                 TAG_DIC[tag] += 1#Ajouter si le tag existe
            else:
                TAG_DIC[tag] = 1#Sinon, enregistrez-en un nouveau et définissez la valeur initiale sur 1.
            
        NEXT_XPATH = browser.find_elements_by_xpath("//*[@id=\"mainContainer\"]/div[4]/div/p/a/span[contains(text(),\'Page suivante\')]")#「Page suivante」が含まれるelementを検索

        if NEXT_XPATH:#Ajouter une PAGE s'il y a une prochaine
            PAGE += 1

        else:
            print("Got tags at last page.")#Sinon, c'est fini
            break

        URL= "https://teratail.com/search?tab=active&page=" + str(PAGE) + "&q=is%3Anot-answered"
        browser.get(URL)#Aller à la page suivante
        WebDriverWait(browser, 2).until(EC.presence_of_all_elements_located)
        print(browser.current_url)

  1. interrompre le traitement La raison pour laquelle cette boucle se termine est que le bouton "Suivant" est introuvable. Je fabrique une double soucoupe lorsqu'une erreur de page se produit. Si cela devient une "erreur de page", il n'y a pas de "bouton suivant", mais je veux éviter de collecter des balises supplémentaires sur la page d'erreur.

break.py


        if browser.title == "Page non trouvée":
            print("Got tags at last page.")#Si une erreur se produit sur la page suivante, le processus se termine.
            break
  1. Post-traitement Nous allons convertir le dictionnaire en Dataframe. Vous pouvez permuter les lignes et les colonnes avec .T dans pd.DataFrame ([TAG_DIC.keys (), TAG_DIC.values ()], index = None) .T. Pratique Pratique.

pandas.py


    #Post-traitement: création d'une Dataframe
    df = pd.DataFrame([TAG_DIC.keys(),TAG_DIC.values()],index=None).T#Convertir en Dataframe
    df.rename(columns={0:"Tag",1:"Count"},inplace =True)#Renommer la colonne
    df.sort_values(by=['Count'],ascending=False,inplace =True)#Trier par ordre décroissant
    df.reset_index(drop=True,inplace=True)#Réaffecter l'index
        
    print(df)

Avec ce sentiment, le résultat est ...

result.py


Got tags at last page.
                        Tag Count
0                       PHP  3139
1                    Python  2623
2                JavaScript  2428
3                      Ruby  1974
4                Python 3.x  1762
5                 WordPress  1563
・
・
[1369 rows x 2 columns]
・
・

Un énorme 1369 lignes sont sorties. "Liste de balises 501" ou quelque chose comme ramasser la corbeille ou compter 1 La cause était qu'il y en avait beaucoup. Il était normal de supprimer les lignes avec un nombre de 100 ou moins en post-traitement. Si vous voulez le rendre plus beau, n'enregistrez pas les mots exclus dans le dictionnaire Je pense qu'il est normal de créer une branche conditionnelle.

C'est tout pour cette fois.

Recommended Posts

[Selenium] Aller à la page suivante sans appuyer sur Suivant
[Selenium] Utilisez l'instruction while pour passer à plusieurs reprises à la "page suivante"
Pour remplacer dynamiquement la méthode suivante en python
[Wagtail] Ajouter une page de connexion au projet Wagtail
À côté d'Excel, le notebook Jupyter pour le moment
Comment profiter de Python sur Android !! Programmation en déplacement !!
[Django] Comment rediriger les utilisateurs non connectés vers la page de connexion
[Selenium] Comment spécifier le chemin relatif de chromedriver?
Déployez la page de gestion en production pour faciliter la maintenance.
Je t'ai écrit pour regarder le signal avec Go