【问题标题】:Web Scraping Thesaurus using Selenium使用 Selenium 抓取 Web Scraping 词库
【发布时间】:2021-06-01 00:00:59
【问题描述】:

我对网络抓取世界还很陌生,但我确实需要在同义词库网站上为我正在进行的项目做一些网络抓取。我已经使用 beautifulsoup4 成功创建了一个程序,该程序询问用户一个单词,然后返回基于同义词库的最可能的同义词。但是,我不仅想要这些同义词,还想要每个词义的同义词(同义词上方的按钮列表在同义词库中描述)。我注意到当单击一个按钮时,类的名称也发生了变化,所以我做了一点挖掘并决定使用 Selenium 而不是 beautifulsoup。 我现在有一个在搜索栏上写一个词并单击它的代码,但是,我无法获得同义词或所述按钮,仅仅是因为 find_element 什么也没找到,并且是新手这个,恐怕我使用了错误的语法。

这是我目前的代码(它寻找“好”的同义词):

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,10).until(
        EC.presence_of_element_located((By.ID, "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">
                ...

&lt;li data-test-pos-tab="true" class=" css-1ha4k0a ew5makj4"&gt; 每一个都是我想点击的按钮。到目前为止,我已经尝试了很多类似代码中显示的东西,还有类似的东西:

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 又找不到这些元素... 为了实现这一目标,我真的很感激一些帮助,即使这只是朝着正确的方向推动而不是提供完整的解决方案。 希望我写了所有需要的信息,如果没有,请告诉我。

【问题讨论】:

  • 如果你使用css selector,那么你必须使用点表示类 - css_selector(".css-ixatld.e1cc71bi0") - 并使用散列表示 id - css_selector("#headword")
  • class_name() 需要单个名称,而 selenium 在有两个名称时会出现问题 - 当它将 class_name 转换为 css_selector 时,它只在名字之前添加点,但之前也需要点第二个名字。所以你必须手动添加第二个点class_name("css-ixatld.e1cc71bi0")
  • 非常感谢,这就像一个魅力:)

标签: python selenium screen-scraping thesaurus


【解决方案1】:

如果你使用css selector,那么你必须使用dot 来代替class

css_selector(".css-ixatld.e1cc71bi0") 

hashid

css_selector("#headword") 

就像您在文件中使用的一样 .css

css selector 中,您还可以使用CSS 中提供的其他方法。
css selectorsw3schools.com


Selenium 将 class_name 转换为 css selectorclass_name() 需要单个名称,并且当有两个或多个名称时,Selenium 会出现问题。当它将class_name 转换为css_selector 时,它只在名字之前添加dot,但在第二名和其他名字之前也需要dot。所以你必须手动添加第二个dot

class_name("css-ixatld.e1cc71bi0")

【讨论】:

    【解决方案2】:

    看看这是否有效:

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

    【讨论】:

    • 我不想实际点击它们,只需要访问文本来存储同义词。但是我似乎无法单击按钮,因此我将尝试类似的操作。
    猜你喜欢
    • 2021-10-15
    • 2022-09-23
    • 2019-01-31
    • 2018-07-08
    • 2021-02-07
    • 2016-04-18
    • 2022-01-08
    • 2020-11-15
    • 2023-02-18
    相关资源
    最近更新 更多