在具有 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
。所以你可以使用 selenium
或 requests_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
我正在尝试为此 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
。所以你可以使用 selenium
或 requests_html
。确实有很多模块可以做到这一点。
现在,我们在 table 上有了另一个选项,可以跟踪数据的呈现位置。我能够找到用于从 back-end
API
检索数据并将其呈现给用户端的 XHR 请求。
You can get the
XHR
request by open Developer-Tools and check Network and checkXHR/JS
requests made depending of the type of call such asfetch
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