【问题标题】:Xpath selector doesn't filter out class when iterating over selector list迭代选择器列表时,Xpath 选择器不会过滤掉类
【发布时间】:2019-11-30 02:43:19
【问题描述】:

我正在抓取这个网站:https://www.oddsportal.com/darts/europe/european-championship/results/

这个网站使用 javascript 渲染表格数据,因此我在 docker 容器中使用了 scrapy-splash 插件。

我想在遍历选择器列表“tableRows”时过滤掉所有具有“dark center”类的行。 但是在迭代时,xpath 选择器会在每次迭代时查询与每个项目相对的整个 SelectorList

tableRows = response.xpath('//table[contains(@id, "tournamentTable")]/tbody/tr')

    for row in tableRows:
        print(row)
        if row.xpath('//*[contains(@class, "dark center")]') is not None:
            print(True)

我的输出:

<Selector xpath='//table[contains(@id, "tournamentTable")]/tbody/tr' data='<tr class="dark center" xtid="39903"><th'>
True
<Selector xpath='//table[contains(@id, "tournamentTable")]/tbody/tr' data='<tr class="center nob-border"><th class='>
True

为什么类'center nob-border'返回True?

【问题讨论】:

    标签: python python-3.x scrapy


    【解决方案1】:

    您的 XPath 有点错误。看看this answer. 您错过了第二个 XPath 表达式中的点。简而言之:

    # Search document root for mentioned node.
    row.xpath('//*[contains(@class, "dark center")]')
    
    # In fact it's the same as
    response.xpath('//*[contains(@class, "dark center")]')
    
    # Search element root for mentioned node(what you're really need) is
    row.xpath('./*[contains(@class, "dark center")]')
    # or .//*[contains(@class, "dark center")] possibly, depending on DOM structure
    

    大更新在这里.. 啊哈哈...事实上我真的很愚蠢。 好吧...实际上,您的代码中有两个错误。第一个是我提到的 Xpath 表达式。第二个是比较运算符。

    row.xpath('any XPath here') is not None
    

    将始终返回 True。由于函数返回类型是一个列表,它可以是空的,但它永远不能是 NoneType。就这样。我还改进了 Xpath 选择器... 最后,您需要的完全准确的代码是:

    tableRows = response.xpath('//table[contains(@id, "tournamentTable")]/tbody/tr')
    
    for row in tableRows:
        print(row)
        if row.xpath('./self::tr[contains(@class, "dark center")]'):
            print(True)
    

    【讨论】:

    • 两个建议的结果相同。我很困惑
    • row.xp... 和 response.xp...``` 怎么一样?当row.xp... 只是选择器列表中的一项时?
    • 顺便说一句。您是否知道您正在尝试获取 js 呈现的数据?我的意思是在呈现 javascript 之前,文档正文中根本没有这样的数据。
    • 试试scrapy view https://www.oddsportal.com/darts/europe/european-championship/results/,看看哪些数据scrapy可以操作。
    • 是的,我正在使用 scrapy-splash 插件
    【解决方案2】:

    这里的主要问题是下载页面中没有dark center。这些类是在页面加载后由一些 javascript 代码创建的。如果您在 View Page Source 中搜索它们,您将找不到它们。

    但是,您想要的数据在另一个 url 中。比如:https://www.oddsportal.com/ajax-sport-country-tournament-archive/14/rwHQ6U5F/X0/1/0/1/?_=1563816992686

    $ curl -s https://www.oddsportal.com/ajax-sport-country-tournament-archive/14/rwHQ6U5F/X0/1/0/1/\?_\=1563816992686 | cut -c -500
    
    -|-{"s":1,"d":{"html":"<table class=\" table-main\" id=\"tournamentTable
    \"><colgroup><col width=\"50\" \/><col width=\"*\" \/><col width=\"50\" 
    \/><col width=\"50\" \/><col width=\"50\" \/><col width=\"50\" \/><col width=\"50\" \/><\/colgroup><tbody><tr class=\"dark center\" xtid=\"39903\"
    ><th class=\"first2 tl\" colspan=\"7\"><a class=\"bfl sicona s14\" href=\"
    \/darts\/\">Darts<\/a><span class=\"bflp\">\u00bb<\/span><a class=\"bfl\"
    href=\"\/darts\/europe\/\"><span class=\"ficon f-6\">&nbsp;<\/
    

    您必须了解如何正确组合该网址。我只知道最后一个参数是时间戳。祝你好运。

    【讨论】:

    • 谢谢,对不起,我应该提到我正在 docker 容器上运行 splash 来渲染 javascipt 以用于 scrapy
    【解决方案3】:

    如果您想要所有具有“dark center”类的元素,您可以使用:

    //tr[@class="dark center"]
    

    为什么类'center nob-border'返回True?

    结果为真,因为您正在搜索所有 tr 标签而不指定类或 id,并且 contains 不适用于多个关键字。它们之间是 using 和 or 语句。

    参考: XPath with multiple contains on different elements

    【讨论】:

    • 此选择器返回相同的结果,我在选择器列表中的一个而不是整个表上执行 xpath 选择器。因此,行变量。
    【解决方案4】:

    满足您要求的正确 xpath 是 //table[contains(@id, "tournamentTable")]//tr[@class='dark center']

    使用此 xpath,您将在表中搜索 id tournamentTable 和类 dard center 的行

    希望对你有帮助:)

    【讨论】:

      【解决方案5】:

      尝试获取它们:

      tableRows = response.xpath('//table[contains(@id, "tournamentTable")]/tbody/tr').getall()
          for row in tableRows:
              print(row)
              if row.xpath('//*[contains(@class, "dark center")]').get() is not None:
                  print(True)
      

      【讨论】:

      • 同样的结果。我很困惑
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 2017-11-07
      • 1970-01-01
      • 2020-03-05
      • 2012-07-28
      相关资源
      最近更新 更多