在具有 python 的网站上抓取 "onclick" 对象 table

Web scraping an "onclick" object table on a website with python

我正在尝试为此 link 抓取数据:page

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

Table appears on click

我用bs4做了一些网页抓取,但是我认为这是selenium的工作(如果我错了,请纠正我),我不是很熟悉。

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

我现在很困惑,已经尝试 select 通过迭代 and/or 打印对象 table 中的内容,它要么说 对象不可迭代或者是None.

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()

请告诉我如何继续从 table 弹出窗口中提取数据。

请尝试以下解决方案

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

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

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

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

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

You can get the XHR request by open Developer-Tools and check Network and check XHR/JS requests made depending of the type of call such as 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