问题描述
我对网络抓取世界还很陌生,但我确实需要在同义词网站上为我正在从事的项目做一些网络抓取。我已经使用beautifulsoup4成功创建了一个程序,该程序要求用户输入一个单词,然后根据同义词返回最可能的同义词。但是,我不仅希望拥有这些同义词,还希望拥有该词的每一种含义的同义词(在同义词库中通过同义词上方的按钮列表进行描述)。我注意到当点击一个按钮时,类的名称也会改变,所以我做了一些挖掘并决定使用 Selenium 而不是 beautifulsoup。 我现在有一个代码可以在搜索栏上写一个词并点击它,但是,我无法获得同义词或所说的按钮,仅仅是因为 find_element 什么也没找到,而且是新手这个,恐怕我使用了错误的语法。
这是我目前的代码(它寻找“good”的同义词):
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.webdriver.common.keys import Keys
import time
PATH = "C:\Program Files (x86)\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://thesaurus.com")
search = driver.find_element_by_id("searchbar_input")
search.send_keys('good')
search.send_keys(Keys.RETURN)
try:
headword = webdriverwait(driver,10).until(
EC.presence_of_element_located((By.ID,"headword"))
)
print(headword.text)
#buttons = headword.find_element_by_class_name("css-bjn8wh e1br8a1p0")
#print(buttons.text)
meanings = webdriverwait(driver,"meanings"))
)
print(meanings.text)
#words = meanings.find_elements_by_class_name("css-1kg1yv8 eh475bn0")
#print(words.text)
except:
print('Failed')
driver.quit()
对于第一部分,我想访问按钮。词条只是包含我想要按下的所有按钮的元素。这是根据检查工具的词条元素:
<div id="headword" class="css-bjn8wh e1br8a1p0">
<div class="css-vw3jp5 e1ibdjtj4">
*unecessary stuff*
<div class="css-bjn8wh e1br8a1p0">
<div class="postab-container css-cthfds ew5makj3">
<ul class="css-gap396 ew5makj2">
<li data-test-pos-tab="true" class="active-postab css-kgfkmr ew5makj4">
<a class="css-sc11zf ew5makj1">
<em class="css-1v93s5a ew5makj0">adj.</em>
<strong>pleasant,fine</strong>
</a>
</li>
<li data-test-pos-tab="true" class=" css-1ha4k0a ew5makj4">
*similar stuff*
<li data-test-pos-tab="true" class=" css-1ha4k0a ew5makj4">
...
这些 <li data-test-pos-tab="true" class=" css-1ha4k0a ew5makj4">
中的每一个都是我想要点击的按钮。到目前为止,我已经尝试了很多东西,比如代码中显示的东西,还有:
buttons = headword.find_elements_by_class_name("css-1ha4k0a ew5makj4")
buttons = headword.find_elements_by_css_selector("css-1ha4k0a ew5makj4")
buttons = headword.find_elements_by_class_name("postab-container css-cthfds ew5makj3")
buttons = headword.find_elements_by_css_selector("postab-container css-cthfds ew5makj3")
但无论如何,Selenium 都能找到这些元素。
对于第二部分,我想要同义词。这是意义元素:
<div id="meanings" class="css-16lv1yi e1qo4u831">
<div class="css-1f3egm3 efhksxz0">
*unecessary stuff*
<div data-testid="word-grid-container" class="css-ixatld e1cc71bi0">
<ul class="css-1ngwve3 e1ccqdb60">
<li>
<a font-weight="inherit" href="/browse/acceptable" data-linkid="nn1ov4" class="css-1kg1yv8 eh475bn0">
</a>
</li>
<li>
<a font-weight="inherit" href="/browse/bad" data-linkid="nn1ov4" class="css-1kg1yv8 eh475bn0">
...
其中每个元素都是我想得到的同义词。与前一个案例类似,我尝试了几种方法,例如:
synGrid = meanings.find_element_by_class_name("css-ixatld e1cc71bi0")
synGrid = meanings.find_element_by_css_selector("css-ixatld e1cc71bi0")
words = meanings.find_elements_by_class_name("css-1kg1yv8 eh475bn0")
words = meanings.find_elements_by_css_selector("css-1kg1yv8 eh475bn0")
Selenium 再次找不到这些元素... 为了实现这一目标,我真的很感激一些帮助,即使这只是朝着正确的方向推进而不是提供完整的解决方案。 希望我写了所有需要的信息,如果没有,请告诉我。
解决方法
看看这是否有效:
meanings = driver.find_elements_by_xpath(".//div[@id='meanings']/div[@data-testid='word-grid-container']/ul/li")
for e in meanings:
e.find_element_by_tag_name("a").click()
//Add a implicit wait if you need
driver.back()
,
如果您使用 css selector
,那么您必须将 dot
用于 class
css_selector(".css-ixatld.e1cc71bi0")
和 hash
用于 id
css_selector("#headword")
就像您在文件中使用的一样 .css
在 css selector
中,您还可以使用 CSS
中可用的其他方法。
请参阅 w3schools.com
Selenium 将 class_name
转换为 css selector
,但 class_name()
需要单个名称,当有两个或多个名称时,Selenium 会出现问题。当它将 class_name
转换为 css_selector
时,它仅在名字之前添加 dot
,但在第二名和其他名称之前也需要 dot
。所以你必须手动添加第二个 dot
class_name("css-ixatld.e1cc71bi0")