【问题标题】:Web scraping after clicking on two buttons单击两个按钮后的网页抓取
【发布时间】:2021-04-09 20:17:01
【问题描述】:

我正在尝试通过单击 2 个单选按钮从该网站 http://rgphentableaux.hcp.ma/Default1/ 抓取数据,然后从类似 enter image description here 这样的列表中进行选择

我需要为该列表中的所有可用选项执行此操作,并将表添加到我拥有的数据框中 这是我迄今为止尝试过的,但没有奏效

    from bs4 import BeautifulSoup 
    pip install selenium
    from selenium import webdriver
    browser=webdriver.Chrome()
    url = "http://rgphentableaux.hcp.ma/Default1/"
    browser.get(url) #navigate to the page
    browser.find_element_by_xpath(".//input[@type='radio' and 
                     @value='5']").click()
    browser.find_element_by_id("CGEO").click()
    time.sleep(3)
    browser.find_element_by_xpath(".//input[@type='button' and 
                    @value='Afficher']").click()
    tabs = browser.find_elements_by_id('IEE')
    innerHTML = browser.execute_script("return 
                 document.body.innerHTML")
    soup_level2=BeautifulSoup(innerHTML, 'html.parser')

Ps:我也需要获取这里的表格

【问题讨论】:

    标签: python pandas selenium web-scraping beautifulsoup


    【解决方案1】:

    您可以通过模仿页面发出的请求来使用requestsbs4 完成所有操作。您只需按正确的顺序循环区域,并将当前区域编号添加到每个请求中的'CGEO' 参数。


    这个:

    soup = bs(s.get(url).content, 'lxml')
    regions = [i.text.strip() for i in soup.select('#REGIONSLIST option')]
    

    从登陆 url 收集区域名称的初始列表。


    这个:

    for k,v in regions.items():
        params = (('type', 'Region'), ('CGEO', v), ('them', '5'))
    

    使用区域的option 标记value 属性设置CGEO 参数,例如 Tanger-Tetouan-Al Hoceima'01'

    Region 选项在type 参数中设置。

    Langues locales utilisées 选项在them 参数中设置,即'5'


    这个:

    for y in range(3):
        row.extend([data[i-y+2]['DATA2014']])
    

    只是颠倒项目的顺序,使data 内每个字典中的Ens, Fem, Masc 以所需的Masc, Fem, Ens 输出顺序添加到row


    派:

    import requests
    import pandas as pd
    from bs4 import BeautifulSoup as bs
    
    def add_rows(region, data):
        for i in range(0, len(data)//3, 3):
            row = [region, data[i]['INDICATEUR'].split('_')[-1]]
            for y in range(3):
                row.extend([data[i-y+2]['DATA2014']])
            final.append(row)
            
    url = 'http://rgphentableaux.hcp.ma/Default1'    
    headers= {'User-Agent': 'Mozilla/5.0',  'Referer': url}    
    final = []
    
    with requests.Session() as s:
        s.headers = headers
        soup = bs(s.get(url).content, 'lxml')
        regions = {i.text.strip():i['value'].strip() for i in soup.select('#REGIONSLIST option')}
        
        for k,v in regions.items():
            params = (('type', 'Region'), ('CGEO', v), ('them', '5'))
            r = s.get(f'{url}/getDATA/', params=params)
            data = r.json()
            add_rows(k, data)
        
    df = pd.DataFrame(final, columns = ['Region', 'Lang', 'Masc', 'Fem', 'Ens'])
    print(df)
    

    编辑:

    要获取所有 3 个表(ensemble、urbain、rural),请调整自定义函数,如下所示并添加附加循环 for n in range(0, len(data), block)

    import requests
    import pandas as pd
    from bs4 import BeautifulSoup as bs
    
    def add_rows(table, region, data_block):
        for i in range(0, len(data_block), 3):
            row = [table, region, data_block[i]['INDICATEUR'].split('_')[-1]]
            for y in range(3):
                row.extend([data_block[i-y+2]['DATA2014']])
            final.append(row)
            
    url = 'http://rgphentableaux.hcp.ma/Default1'    
    headers= {'User-Agent': 'Mozilla/5.0',  'Referer': url}
    tables = ['ens', 'urb', 'rur']
    final = []
    
    with requests.Session() as s:
        s.headers = headers
        soup = bs(s.get(url).content, 'lxml')
        regions = {i.text.strip():i['value'].strip() for i in soup.select('#REGIONSLIST option')}
        
        for k,v in regions.items():
            params = (('type', 'Region'), ('CGEO', v), ('them', '5'))
            r = s.get(f'{url}/getDATA/', params=params)
            data = r.json()
            block = len(data)//3
            
            for n in range(0, len(data), block):
                table = tables[n//block]
                add_rows(table, k, data[n:n+block])
                
    df = pd.DataFrame(final, columns = ['Table', 'Region', 'Language', 'Masc', 'Fem', 'Ens'])
    print(df)
    

    【讨论】:

    • 非常感谢它的工作,你是一个救星。
    • 很抱歉打扰您,但我怎样才能得到其他表,即“Urbain”和“Rural”中的表,而不仅仅是“Ensemble”中的表。谢谢
    • 您的意思是 Communes et centres urbains 以及 Provinces
    • 不,我的意思是在表的正上方出现三个选项“Ensemble”、“Urbain”和“Rural”,我也需要获得那里的表,而不仅仅是 '合奏'我希望它很清楚。
    • 我编辑了帖子并添加了一张图片,以便您查看
    【解决方案2】:

    要选择文本为 Langues locales utiliséesRegion 的项目并刮掉表格,您可以使用以下解决方案:

    driver.get("http://rgphentableaux.hcp.ma/Default1/")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@text='Langues locales utilisées']"))).click()
    driver.find_element_by_xpath("//input[@value='Region']").click()
    driver.execute_script("return arguments[0].scrollIntoView(true);", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@value='Choisir une entitée']"))))
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@value='Choisir une entitée']"))).click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[contains(., 'Tanger-Tetouan-Al Hoceima')]"))).click()
    driver.find_element_by_xpath("//input[@value='Afficher']").click()
    print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//table[@class='tableau']/tbody"))).text)
    

    控制台输出:

    Population municipale 16 747 522 16 862 562 33 610 084
    Répartition selon les grands groupes d'âges
    Moins de 6 ans 12.4 11.8 12.1
    De 6 à 14 ans 16.5 15.7 16.1
    De 15 à 59 ans 61.8 63.0 62.4
    60 ans et plus 9.3 9.5 9.4
    Répartition selon le groupe d'âges quinquennal
    0-4 ans 10.4 9.9 10.2
    5-9 ans 9.2 8.8 9.0
    10-14 ans 9.3 8.8 9.0
    15-19 ans 8.9 8.8 8.9
    20-24 ans 9.0 9.1 9.1
    25-29 ans 8.2 8.4 8.3
    30-34 ans 7.7 8.0 7.8
    35-39 ans 6.8 7.2 7.0
    40-44 ans 6.3 6.5 6.4
    45-49 ans 5.3 5.6 5.4
    50-54 ans 5.3 5.4 5.3
    55-59 ans 4.2 4.0 4.1
    60-64 ans 3.4 3.3 3.4
    65-69 ans 1.9 1.9 1.9
    70-74 ans 1.6 1.8 1.7
    75 ans et plus 2.4 2.6 2.5
    État matrimonial
    Célibataire 57.9 48.4 53.2
    Marié 40.8 42.0 41.4
    Divorcé 0.7 2.4 1.6
    Veuf 0.6 7.1 3.9
    Âge moyen au premier mariage 31.3 25.7 28.5
    Fécondité
    Parité moyenne à 45-49 ans / 3.5 /
    Indice synthétique de fécondité / 2.2 /
    

    【讨论】:

      猜你喜欢
      • 2015-01-05
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多