【问题标题】:Web scraping an "onclick" object table on a website with pythonWeb 使用 python 在网站上抓取“onclick”对象表
【发布时间】:2020-07-14 06:50:20
【问题描述】:

我正在尝试抓取此链接的数据:page

如果您点击向上箭头,您会注意到月份部分中突出显示的日期。单击突出显示的日期,将出现一个包含该天已启动投标的表格。我需要做的就是获取日历中每个突出显示日期的每个表中的数据。每天可能有一个或多个投标(最多 7 个)。

Table appears on click

我已经用 bs4 进行了一些网络抓取,但是我认为这是我不太熟悉的 selenium 的工作(如果我错了,请纠正我)。

到目前为止,我已经设法通过 XPATH 找到箭头元素来浏览日历并显示更多月份。之后,我尝试单击随机的一天(在下面的代码中,我单击了 30.03.2020),在该日期上,一个名为“tenders-table cloned”的 html 对象出现在检查的 html 中。无论您在哪一天点击,对象名称都保持不变。

我现在很困,尝试通过迭代选择和/或打印该对象表中的内容,它要么说 object is not iterable 要么

from selenium import webdriver

chrome_path = r"C:\Users\<name>\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)

driver.get("http://www.ibex.bg/bg/данни-за-пазара/централизиран-пазар-за-двустранни-договори/търговски-календар/")
driver.find_element_by_xpath("""//*[@id="content"]/div[3]/div/div[1]/div/i""").click()
driver.find_element_by_xpath("""//*[@id="content"]/div[3]/div/div[2]/div[1]/div[3]/table/tbody/tr[6]/td[1]""").click()

请建议我如何从弹出的表格中提取数据。

【问题讨论】:

    标签: html selenium web-scraping beautifulsoup scrape


    【解决方案1】:

    好吧,我认为没有理由在这种情况下使用selenium,因为它会减慢您的任务。

    网站加载了JavaScript 事件,该事件会在页面加载后动态呈现其数据。

    requests 库将无法即时渲染 JavaScript。所以你可以使用seleniumrequests_html。确实有很多模块可以做到这一点。

    现在,我们在表格上确实有另一个选项,可以跟踪数据的呈现位置。我能够找到 XHR 请求,该请求用于从 back-end API 检索数据并将其呈现给用户端。

    您可以通过打开Developer-Tools 并检查Network 和检查XHR/JS 请求来获取XHR 请求,具体取决于调用类型,例如fetch

    import requests
    import json
    
    data = {
        'from': '2020-1-01',
        'to': '2020-3-01'
    }
    
    
    def main(url):
        r = requests.post(url, data=data).json()
        print(json.dumps(r, indent=4)) # to see it in nice format.
        print(r.keys())
    
    
    main("http://www.ibex.bg/ajax/tenders_ajax.php")
    

    因为我只是一个懒惰的编码员:我会这样:

    import requests
    import re
    import pandas as pd
    import ast
    from datetime import datetime
    
    data = {
        'from': '2020-1-01',
        'to': '2020-3-01'
    }
    
    
    def main(url):
        r = requests.post(url, data=data).json()
        matches = set(re.findall(r"tender_date': '([^']*)'", str(r)))
        sort = (sorted(matches, key=lambda k: datetime.strptime(k, '%d.%m.%Y')))
        print(f"Available Dates: {sort}")
        opa = re.findall(r"({\'id.*?})", str(r))
        convert = [ast.literal_eval(x) for x in opa]
        df = pd.DataFrame(convert)
        print(df)
        df.to_csv("data.csv", index=False)
    
    
    main("http://www.ibex.bg/ajax/tenders_ajax.php")
    

    输出:view-online

    【讨论】:

    • 谢谢伙计!这是完全直接的解决方案!我也在开发工具中查看 XHR,但我发现自己有点困惑。现在清楚多了。谢谢!
    • @sc-coder 欢迎您,您知道如何处理好其余的 :)?
    • 是的,我想我会处理的。再次,非常感谢!
    • @sc-coder 检查更新的答案:P 只是为了记录
    • 不错的一个!相当优雅!一路懒惰! :D
    【解决方案2】:

    请尝试以下解决方案

    driver.maximize_window()
    wait = WebDriverWait(driver, 20)  
    
    
    elemnt=wait.until(EC.presence_of_element_located((By.XPATH, "//body/div[@id='wrapper']/div[@id='content']/div[@class='tenders']/div[@class='form-group']/div[1]/div[1]//i")))
        elemnt.click()
        elemnt1=wait.until(EC.presence_of_element_located((By.XPATH, "//div[@class='form-group']//div[1]//div[3]//table[1]//tbody[1]//tr[6]//td[1]")))
        elemnt1.click()
        lists=wait.until(EC.presence_of_all_elements_located((By.XPATH, "//table[@class='tenders-table cloned']")))
        for element in lists:
             print element.text
    

    【讨论】:

    • 嘿,迪帕克。感谢您的解决方案。请注意,我上面的代码也会找到元素并单击它们以使表格出现。我的问题是如何继续收集单击突出显示的日期后出现的每个表中的数据。我也试过你的解决方案,它返回一个空白页。
    • 谢谢!这可以正常工作并为日历中突出显示的一天提取一个列表。
    • 嗨 Dipak,请注意,αԋɱҽԃ αмєяιcαη 的回答要好得多,而且直截了当。我需要在每个突出显示的日子中识别和提取数据,而不仅仅是一个,他的解决方案要快得多。再次感谢您的解决方案。由于我的帐户还是新帐户,因此恐怕我无法投票赞成您的答案。不过稍后会尝试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    • 2021-07-28
    • 1970-01-01
    • 2020-09-28
    • 2017-02-13
    • 2018-09-01
    • 1970-01-01
    相关资源
    最近更新 更多