如何在Python中从动态页面抓取多个表

时间:2018-11-12 17:17:41

标签: python pandas web-scraping

编辑:

我在链接标签的div标签下找到了嵌入到所有内容的链接-不知道ajax /前端开发人员,我不确定您如何称呼它:看起来像这样:

<a class="tabs__link js-tabs-ranking" href="it" data-ajax-stack="{&quot;itg&quot;:&quot;\/en\/ajax\/ranking\/19\/itg\/18f11c81b4cd83f7b82b47a88d939a9c\/none&quot;,&quot;ipg&quot;:&quot;\/en\/ajax\/ranking\/19\/ipg\/b1c62bbc714bc8823f59f3ec1030a3d7\/none&quot;,&quot;etg&quot;:&quot;\/en\/ajax\/ranking\/19\/etg\/5b2a3871133c7df8954b81ca884d233f\/none&quot;,&quot;img&quot;:&quot;\/en\/ajax\/ranking\/19\/img\/03a4a10eac4baaffa954cebf29c39b1c\/none&quot;,&quot;ijg&quot;:&quot;\/en\/ajax\/ranking\/19\/ijg\/ec301eb70c0b7df824159aaa00d79135\/none&quot;,&quot;icg&quot;:&quot;\/en\/ajax\/ranking\/19\/icg\/81b5589ac9889472dcda9560dd23683d\/none&quot;}" data-type="g" data-xtclick="ranking::tab::overall">General classification</a>

我已经获得了以下代码,以将表放入所有具有多个表和标题的页面之外的所有页面的数据帧中-输入ime,ipe-我进行了if-else尝试以不同方式处理这些页面。

我想做的是将每个表放入其自己的数据帧中,但我不断收到一堆难看的html和结尾的错误“ TypeError:'NoneType'对象不可调用”。我会继续努力,但任何建议都值得欢迎!

import requests
import html5lib
import pandas as pd
from bs4 import BeautifulSoup


#type_dict = {'e':'Stage', 'g':'General Classification'}
tab_dict = {'ite':'Stage',
'ipe':'Points',
'ime':'Mountains',
'ije':'Young riders',
'ice':'Combativity',
'ete':'Teams',
'itg':'General Classification',
'ipg':'Points Classification',
'img':'Mountains Classification',
'ijg':'Young Riders Classification',
'icg':'Combativity Classification',
'etg':'Teams Classification'}
#Add a user input for the URL
start_url = "https://www.letour.fr/en/rankings/stage-19"
base_url = start_url.split('/')[2]

page = requests.get(start_url)
content = page.content
r_table = pd.read_html(content)

#This worked to get the table out into a DataFrame
df = r_table[0]
#print(df['Rider'])
soup = BeautifulSoup(content, "html5lib")

all_links = soup.find_all(class_="tabs__link js-tabs-ranking")
#grabbing the block of ajax links that give URLs to various stage/GC results
for item in all_links:
    myurl = item['data-ajax-stack']
    myurl = myurl.replace('\/', '/').replace('{', '').replace('}', '').replace('"','')
    myurl = dict(x.split(':') for x in myurl.split(','))
#looping through the lists of links and getting the pages
    for key, value in myurl.items():
    r_type = tab_dict[key]
    print("Getting the data for: " + r_type)
    url = ("http://" + base_url + value)
    try:
        if key == "ipe" or key == "ime":

        page = requests.get(url).content
        print(page)
        soup = BeautifulSoup(page, "html5lib")
        #heading = soup.find_all('div', class_="rankingTables__caption")
        for caption in soup.find_all('div', class_="rankingTables__caption"):
            res_caption = caption.text.title()
            print(res_caption)
            res_table = pd.read_html(caption)
            df = res_table[0]
            print(df) #debugging, test
        else:
        page = requests.get(url).content
        soup = BeautifulSoup(page, "html5lib")
        res_table = pd.read_html(page)
        df = res_table[0]
        print(df) #debugging/test

    except ValueError:
        print("No table found for " + key)
        break

我对Python还是比较陌生,并且正在使用一个Web抓取项目来了解更多信息。我在尝试从动态网页获取多个表格数据块时遇到问题。是否有一种简单的方法来获取通过this page的各种点击生成的表格?

下面的代码可以处理默认负载下的结果,但是我希望能够遍历选项卡并将它们全部捕获到同一数据框中。

查看源代码,其中一个标签会随您单击的选项卡而变化:

我考虑过要字典 data-current-type {'e':'Stage','g':'General分类'} data-current-tab {'it':'个人分类', 'ip':'积分', 'im':'山', 'ij':'年轻车手', 'ic':'战斗力', 'et':'Teams'}

这种设计依赖于能够将这些不同的标签传递回页面,我认为这不会起作用。

看看帖子,URL是动态生成的:

https://www.letour.fr/en/ajax/ranking/20/itg/8c7d5ddc44042219f544306cab96c718/subtab https://www.letour.fr/en/ajax/ranking/20/ipg/2d4afa3722c55ad1564caddee00f117f/subtab

有人能指出我最佳工具的方向吗?我已经尝试过搜索和搜索此论坛,但是我一定不能使用正确的标签...

import requests
import pandas as pd

start_url = "https://www.letour.fr/en/rankings/stage-20"

page = requests.get(start_url)

content = page.content
#get the table
res_table = pd.read_html(content)
#Define the DataFrame
df = res_table[0]

2 个答案:

答案 0 :(得分:0)

您可以执行以下操作。我将您提供的链接循环并连接到最终数据框中。

numpy.add

答案 1 :(得分:0)

我不确定链接是动态生成的。刷新页面似乎显示链接是相同的。

话虽如此,您可能要做的是基于选项卡的<a>元素的xpath提取链接。

因此,获取链接的xpath可能是一个命令:

links_xpath = {
    'climber' : "//a[contains(@class, 'tabs__link') and contains(text(), 'Climber')]/@href",
    'points' : "//a[contains(@class, 'tabs__link') and contains(text(), 'Points')]/@href",
    # etc.
}

这将提取链接,然后您可以将其与基本URL合并,并确保无论基本链接如何,您的抓取工具都可以正常工作,至少直到页面布局可能更改为止。