已经完成的抓取会抓取页面上的所有内容。我想将抓取限制在某个部分
Posted
技术标签:
【中文标题】已经完成的抓取会抓取页面上的所有内容。我想将抓取限制在某个部分【英文标题】:Already complete scraping scrapes everything on the page. I would like to limit the scraping to only a certain section 【发布时间】:2022-01-06 15:53:57 【问题描述】:我放置了我拥有的完整且功能正常的抓取的代码。成功抓取页面上的所有元素。
但是,我只想使用与抓取相同的元素抓取页面的一小部分。这个有限的部分已经连同页面的所有元素一起被正确地刮掉了,但我想只刮掉它而不是“全部+它”。链接是here
页面上有4个表格,但我想只抓取一个,即名为“Programma”的表格,即html部分“event-summary event”或 “联赛静态事件摘要联赛”。但本节只有最后一轮的元素(第 14 场比赛)。仅限第 14 场比赛。没有第 15 轮。很明显,随着页面轮次的每次更新,最后一轮也总是被刮掉。
所以我需要插入一些东西,让抓取理解只下载该部分和最后一轮的元素(它已经拥有和抓取)。
代码已经完成并且工作正常,所以我不是在寻找代码服务,而是为了告诉我如何将抓取限制在上面提到的部分。刮削是在 Selenium 中进行的。我想坚持使用 Selenium 和我的代码,因为它已经可以正常工作且完整。谢谢
import selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("url")
driver.implicitly_wait(12)
#driver.minimize_window()
wait = WebDriverWait(driver, 10)
all_rows = driver.find_elements(By.CSS_SELECTOR, "div[class^='event__round'],div[class^='event__match']")
current_round = '?'
for bundesliga in all_rows:
classes = bundesliga.get_attribute('class')
#print(classes)
if 'event__round' in classes:
#round = row.find_elements(By.CSS_SELECTOR, "[class^='event__round event__round--static']")
#current_round = row.text # full text `Round 20`
current_round = bundesliga.text.split(" ")[-1] # only `20` without `Round`
else:
datetime = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__time']")
#Divide la data e l'ora
date, time = datetime.text.split(" ")
date = date.rstrip('.') # right-strip to remove `.` at the end of date
team_home = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__participant event__participant--home']")
team_away = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__participant event__participant--away']")
score_home = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__score event__score--home']")
score_away = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__score event__score--away']")
bundesliga = [current_round, date, time, team_home.text, team_away.text, score_home.text, score_away.text]
bundesliga.append(bundesliga)
print(bundesliga)
【问题讨论】:
仍然找不到html部分“event-summary event”或“leagues-static event-summary-leagues” @DebanjanB 去它说“Programma”的地方。上面写着 Programma 和 Giornata 14 的表格。看我的截图 pasteboard.co/Fj4qU7AMmZnk.jpg 是的,现在可以找到event event--summary
类。所以你只想刮最后几轮。
@DebanjanB 是的,“程序”中的最后一轮(没有结果的那一轮,因此还有待播放)。但它也说第 15 轮,我不想要 15。只有 14。所以很明显,随着页面上的每一轮更新,我只会刮掉最后一轮。元素与我在抓取中的元素相同。谢谢:)
@DebanjanB 你能帮帮我吗?谢谢
【参考方案1】:
我认为您需要做的就是限制all_rows
变量。一种方法是使用文本找到您要查找的选项卡,然后获取父元素。
import selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
driver = webdriver.Firefox()
driver.get("https://www.someurl/some/other/page")
driver.implicitly_wait(12)
#driver.minimize_window()
wait = WebDriverWait(driver, 10)
# all_rows = driver.find_elements(By.CSS_SELECTOR, "div[class^='event__round'],div[class^='event__match']")
############### UPDATE ####################
def parent_element(element):
return element.find_element(By.XPATH, './..')
programma_element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, "//div[text()='Programma']")))
programma_element_p1 = parent_element(programma_element)
programma_element_p2 = parent_element(programma_element_p1)
programma_element_p3 = parent_element(programma_element_p2)
all_rows = programma_element_p3.find_elements(By.CSS_SELECTOR, "div[class^='event__round'],div[class^='event__match']")
filter_rows = []
for row in all_rows:
if "event__match--last" in row.get_attribute('class'):
filter_rows.append(row)
break
else:
filter_rows.append(row)
############### UPDATE ####################
current_round = '?'
for bundesliga in filter_rows:
classes = bundesliga.get_attribute('class')
#print(classes)
if 'event__round' in classes:
#round = row.find_elements(By.CSS_SELECTOR, "[class^='event__round event__round--static']")
#current_round = row.text # full text `Round 20`
current_round = bundesliga.text.split(" ")[-1] # only `20` without `Round`
else:
datetime = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__time']")
#Divide la data e l'ora
date, time = datetime.text.split(" ")
date = date.rstrip('.') # right-strip to remove `.` at the end of date
team_home = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__participant event__participant--home']")
team_away = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__participant event__participant--away']")
# score_home = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__score event__score--home']")
# score_away = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__score event__score--away']")
try:
score_home = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__score event__score--home']")
except (TimeoutException, NoSuchElementException):
MyObject = type('MyObject', (object,), )
score_home = MyObject()
score_home.text = "-"
try:
score_away = bundesliga.find_element(By.CSS_SELECTOR, "[class^='event__score event__score--away']")
except (TimeoutException, NoSuchElementException):
MyObject = type('MyObject', (object,), )
score_away = MyObject()
score_away.text = "-"
bundesliga = [current_round, date, time, team_home.text, team_away.text, score_home.text, score_away.text]
bundesliga.append(bundesliga)
print(bundesliga)
【讨论】:
我发现你的代码,虽然很特别,但在第 14 轮和第 15 轮都被刮掉了。事实上,我注意到了第 15 轮的科隆-奥古斯塔比赛。你的代码可能会分散注意力。正如您在问题中看到的那样,我用红色突出显示我只想在第 14 轮刮。我想自己解决它,但我无法做到,因为我是 Python 的初学者。你能纠正你的答案吗?你太棒了! @Johan.D.只是为了确认您要暂时排除第 15 轮,然后在第 15 轮和第 16 轮在表中时将其包括在内? @Johan.D.添加了更多更新 我得到一个错误:除了 TimeoutException: NameError: TimeoutException 没有定义。我确认我要排除第 15 轮。我不明白您的意思是“然后在第 15 轮和第 16 轮在表中时包含它”。几天后网页将更新,第 14 轮将消失,所以我想刮下一轮将是 15(只有 15,但不是第 16 轮)。现在我只想刮 14但不是 15。更新后,下周我想只刮 15 而不是 16。然后我又想刮 16 而不是 17,依此类推。 @Johan.D.感谢您的确认,我更新了答案以包含TimeoutException
的导入。以上是关于已经完成的抓取会抓取页面上的所有内容。我想将抓取限制在某个部分的主要内容,如果未能解决你的问题,请参考以下文章
如何使用python和beautifulsoup4循环抓取网站中多个页面的数据
使用 selenium 在 LinkedIn 上抓取个人资料网址