Xpath

2019-11-26  本文已影响0人  iDucky131

Xpath

Xpath在Pycharm中运行

Xpath默认是通过命令行进行运行的,我们可以采用下面方法进行修改,从而能够直接在pycharm中设置断点,从而进行Debug

  1. 在项目下创建一个begin.py文件 image
  2. 在begin.py中填写代码

from scrapy import cmdline
cmdline.execute('scrapy crawl douban -o douban.csv'.split())

其中''内为命令行执行语句

  1. 修改配置


    image

Xpath解析问题猜的坑

Xpath语法中的///起初真的让人搞的头痛,下面记录一下爬取中国大学排名时出现的错误。

image

我们可以看出需要爬取的内容全部在class为hidden_zhpm中的tbody中,每一个大学的信息都是一个名为alt xh-highlight的tr,我的思路是从页面中先获取整个tbody,我编写的代码为:

node_list=response.xpath("//tbody[@class='hidden_zhpm']/tr")

这行代码是没有问题的,问题出现在我处理每一个tr标签的时候:

for node in node_list:
    rank=node.xpath("//tr[@class='alt']/td[0]").extract()[0]
    print(rank)

我在测试是否爬取排名正确的时候,使用这段代码测试,发现输出的全部为1,也就是排名没有改变;然后我将node.xpath("//tr[@class='tr']/td[0]").extract()输出后发现是一个list,里面有所有大学的排名,这也就可以解释为什么我[0]时输出的一直是1.

那么问题来了,为什么我获取的是所有大学的排名,而我只想获取每个tr标签下的排名信息,原因出现在第二次的xpath中.

item['rank']=node.xpath("./td[1]/text()").extract()[0]

我使用//进行匹配,但是这个是从根节点进行匹配,匹配根节点下所有名为alt的tr,也就是说所有大学的信息都被匹配出来了,这时候我获取td[0]就将所有大学的排名选了出来,所以extract()后的内容是一个包含所有大学排名的list,如果想从每个tr标签下筛选内容应该使用:./

item['rank']=node.xpath("./td[1]/text()").extract()[0]

.表示从node开始的路径继续选取,所以每个node下就只能筛选出当前node的排名。

这个bug我改了很久,原因还是对Xpath语法不熟悉,在和学长讨论后我觉得他的解释很清晰,这里拿来看一下:

类似linux:

//是当前文档匹配所有后序表达的意思

单独的/是指根目录

.表示当前结点

在for循环中,每个node是一个selector,当使用./时是在当前selector下开始搜索,而使用//时是在当前文档中进行搜索,而不是从当前节点向下搜索

另外经过观察,我觉得///的区别是:

上一篇 下一篇

猜你喜欢

热点阅读