【问题标题】:how to recursively parse tree of nested comments via selenium?如何通过硒递归解析嵌套评论树?
【发布时间】:2020-07-21 20:15:40
【问题描述】:

我需要用用户名刮掉 cmets 并回复 cmets,日期来自这个 website

cmets 树位于 div 容器“comment-list”内,每个评论可能有一个递归结构(如果有回复):

“comment-list”包含“comment-item”列表。

每个“comment-item”有 4 个部分:元数据(用户名、时间)、实际评论、回复

  • 评论项目内容:

    • 元数据:
      • 用户名
      • 发布时间
    • div 'comment-text' p ACTUAL COMMENT /p

    如果存在回复,则重复评论项:

    • 评论项目
    • 评论项目

这是尸体:

<div class = 'tn-comment-list'>
   <div class ='tn-comment-item'>
      <div class = 'tn-comment-item-content'>
         <div class = 'tn-comment-item-content-metadata'> 
            <span class = 'tn-user-name'>username 1 </span>
            <time> july 20 2020 18:02 </time>
         </div>
         <div class = 'tn-comment-item-content-text'>
            <p> bla bla comment 1 </p>
         </div>
         <div class = 'tn-comment-item'>... </div> //reply1
         
         <div class = 'tn-comment-item'>... </div>//reply 2
         
      </div>
   </div>
</div>

我没有递归地做,而是试图找到所有 cmets (comment-item) 的元素,不管它们是否是答案。

from selenium import webdriver

news_url = 'https://tengrinews.kz/kazakhstan_news/strogiy-karantin-vvodyat-v-mangistauskoy-oblasti-408772/'

driver = webdriver.Chrome()
driver.get(news_url)

comments_list = driver.find_elements_by_xpath("//div[@class='tn-comment-item']")
print(type(comments_list))
print('length of comments %d ' % len(comments_list))

cmets_list 的长度是 21,但我不知道如何遍历它。另外,我认为递归解析仍然是个好主意。

如何递归解析得到所有的cmets?

【问题讨论】:

    标签: python selenium parsing recursion


    【解决方案1】:

    我玩得很开心!

    我尝试了我通常会在 c# 中执行的操作 - 即收集元素列表,使用 for each 进行迭代并执行嵌套 element.find... - 但它不起作用。我不知道是 python 还是网站,或者只是我,但我必须以不同的方式做事。

    它是建立在动态构造和迭代 xpaths 之上的递归函数:

    def PrintRecursiveComments(rootXpath, level):
        ##from the root- this is the path to element with text - there is only 1
        ##textPath = '/div[@class="tn-comment-item-content-text"]/p'
        textPath = '/div/p'
        ##from the root - this is a nested child comment
        repeatingPattern = '/div[@class="tn-comment-item"]/div[@class="tn-comment-item-content"]'
    
        ##get the comment blocks at this level
        comments = driver.find_elements_by_xpath(rootXpath)
        if (len(comments) > 0 ):
            for i in range(len(comments)): # i know it's weird on the surface - need 'i' to iterate 
                print('   -   >  level %d', level)
                print('   -   > comments at this level %d', len(comments))
                try:
                    #need to use driver - won't let me find inside comments list
                    #creating format (//xpath)[i]
                    commentObject = driver.find_element_by_xpath('('+ rootXpath +')' +'['+str(i+1)+']' + textPath)
                    print (commentObject.text)
                    #update the root to contain any children
                    newrootXpath = '('+ rootXpath +')' +'['+str(i+1)+']' + repeatingPattern
                    PrintRecursiveComments(newrootXpath, level+1)
                except NoSuchElementException:
                    print("exception occurred")
                    pass
                print('') #line break
    

    我把调试行留在了那里,因为它有助于输出

    这样称呼它:

    rootList = '//div[@class="tn-comment-list"]/div[@class="tn-comment-item"]/div[@class="tn-comment-item-content"]'
    
    PrintRecursiveComments(rootList,1)
    

    仅供参考 - 也需要此导入:

    from selenium.common.exceptions import NoSuchElementException
    

    最后 - 我注意到,如果 cmets 部分已展开,您只能从 cmets 获取文本。您可能需要更多步骤和一些同步。有一个 webdriverwait 的谷歌(那里有很多例子)

    这是我与网站的输出。 cmets的水平对我来说很合适:

    【讨论】:

    • edwards - 该死的,我也在想它!如果它是隐藏的,我无法获得 cmets 部分......!我没有展开 - 没有点击按钮“展开 cmets”
    • 我什至不知道按钮是这么说的。我只用俄语查看了该网站!对于“扩展 cmets”,您需要 webdriver 等待 + 按钮单击还是从这里获得?
    • 我从你那里得到的,我有一种模糊的感觉,我应该这样做。但是因为我可以在检查器中看到评论文本 - 我认为它们可以通过 webdriver 访问.. 结果不是!
    • 我看到 print(---> 'level %d' , level) 有错字,最后一级应该是 i
    • 打印行仅用于调试 - 不应对输出产生太大影响。级别是深度 a,i 是通过每条消息的迭代。使用 (i) 的更改是使它起作用的最后一件事。它没有调试行,因为它在它之后单击到位。我不知道您需要什么输出,但这一切都适合您,因此请根据需要进行修改:-)
    猜你喜欢
    • 1970-01-01
    • 2020-01-26
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 2012-09-17
    • 2019-09-21
    相关资源
    最近更新 更多