python - 通过属性获取元素并使用驱动程序单击 webscraping 中的子元素 - Python
问题描述
来自 Indeed.com 的网页抓取结果
- 在“加利福尼亚州洛杉矶”中搜索“Junior Python”(完成)
- 有时会打开弹出窗口。如果出现弹出窗口,请关闭窗口。(完成)
- 前 3 名的结果是赞助的,所以跳过这些并进入真正的结果
- 单击结果摘要部分,打开带有完整摘要的侧面板
- 抓取完整的摘要
- 单击结果摘要时,URL 会发生变化。而不是打开新窗口,我想刮掉侧面板的完整摘要
- 每个真实结果都在('div':{'data-tn-component':'organicJob'})
. 我可以使用 BeautifulSoup 获得职位、公司和简短摘要。但是,我想在侧面板上获得完整的摘要。
问题
1)当我尝试点击链接(使用 Selenium)(职位或简短摘要,打开侧面板)时,代码只会点击第一个链接,即“赞助”。无法在 id='jobOrganic' 下找到并点击真实结果
2)一旦(手动)单击实际结果,我可以看到完整的摘要侧面板位于下方<td id='auxCol'>
,在此下方。完整的摘要包含在<p>
标签中。当我尝试使用 selenium 抓取完整摘要findAll('div':{'id':'vjs-desc'})
时,我得到的只是空白结果 []。
3) 打开侧面板时,url 也会发生变化。我尝试使用 Selenium 让驱动程序获取新的 url,然后通过 url 获取结果,但我得到的只是第一个赞助结果,这不是我想要的。我不确定为什么 BeautifulSoup 不断获得赞助的结果,即使我在'id='jobOrganic'
真实结果下运行代码也是如此。
这是我的代码。在过去的两天里,我一直在研究这个问题,浏览了 stackoverflow、文档和谷歌,但找不到答案。我希望有人能指出我做错了什么以及为什么我无法获得完整的摘要。
感谢和抱歉这么久。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup as bs
url = 'https://www.indeed.com/'
driver = webdriver.Chrome()
driver.get(url)
whatinput = driver.find_element_by_id('text-input-what')
whatinput.send_keys('Junior Python')
whereinput = driver.find_element_by_id('text-input-where')
whereinput.click()
whereinput.clear()
whereinput.send_keys('Los Angeles, CA')
findbutton = driver.find_element_by_xpath('//*[@id="whatWhere"]/form/div[3]/button')
findbutton.click()
try:
popup = driver.find_element_by_id('prime-popover-close-button')
popup.click()
except:
pass
这就是我卡住的地方。结果摘要在 {'data-tn-component':'organicJob'}, span class='summary' 下。单击此按钮后,将打开侧面板。
soup = bs(driver.page_source,'html.parser')
contents = soup.findAll('div',{"data-tn-component":"organicJob"})
for each in contents:
summary = driver.find_element_by_class_name('summary')
summary.click()
这会打开侧面板,但它会单击整个页面中的第一个赞助链接(赞助链接),而不是真正的结果。由于某种原因,这基本上超出了“organicJob”结果集。
url = driver.current_url
driver.get(url)
单击链接(赞助)后,我尝试设置新网址以测试我是否甚至可以获得侧面板的完整摘要(尽管是赞助的,作为测试目的)。
soup=bs(driver.page_source,'html.parser')
fullsum = soup.findAll('div',{"id":"vjs-desc"})
print(fullsum)
这实际上会打印出侧面板的完整摘要,但它会在整个循环中一遍又一遍地打印相同的第一个结果,而不是移动到下一个结果。
解决方案
问题是您正在div
使用漂亮的汤来获取 s,但是单击使用不知道您收集的 div 的 selenium。
当您使用对象find_element_by_class_name()
的方法时driver
。它搜索整个页面而不是您想要的 div 对象each
(在 for 循环中)。因此,它最终在每次迭代中从整个页面中获取相同的第一个结果。
一,仅使用 selenium 可以快速解决问题(但这会更慢)
elements = driver.find_elements_by_tag_name('div')
for element in elements:
if "organicJob" in element.get_attribute("data-tn-component"):
summary = element.find_element_by_class_name('summary')
summary.click()
上面的代码将搜索所有的 div 并遍历它们以找到data-tn-component
属性包含organicJob
. 一旦找到一个,它将搜索具有类名的元素summary
并单击该元素。
推荐阅读
- python - 从优势列表中挑选出最好的元素
- node.js - 无法在 Mongoose 中填充嵌套模式引用
- python - 如何去除旧文档图像背景中的噪点
- reactjs - React-native useState 更新甚至认为它没有被调用
- javascript - 如何为文本中的每个单词添加淡入淡出动画
- javascript - 如何使用 javascript 将删除按钮添加到列表项?
- c++ - 关于 C++ 中与宏相关的某些语法的问题
- c# - 在 xaml 中设计类似 win 10 的搜索框
- firebase - 我想在我的颤振应用程序中从 firebase 数据库中获取当前用户数据
- html - Css:通过将按钮悬停在包含按钮的 div 内来触发同级 div