分享

Scrapy-xpath用法以及实例

 stoneccf 2019-01-17

xpath的语法

xpath语法-谓语

创建Scrapy项目

scrapy startproject ArticleSpider
  • 1

创建scrapy爬虫

cd ArticleSpider
scrapy genspiderjobbole blog.
  • 1
  • 2

使用方法

可以直接在chrome->F12开发者工具中复制xpath

这里介绍一种测试的方法

平时我们在pycharm或者编辑器需要每次运行,就需要一次次请求,这里可以用以下的方法:
假设我们需要爬取伯乐在线的一篇文章,链接为 http://blog./112614/
我们爬取一篇文章的标题,发布时间,点赞数,收藏数,评论数

所有字段均以字符串形式存储

命令行执行如下

scrapy shell http://blog./112614/
  • 1

之后,我们可以通过以下命令获取相应内容,response.xpath()会返回<class 'scrapy.selector.unified.SelectorList'>类型,可以通过extract()方法获取内容,返回列表

In [1]: title = response.xpath('//*[@id="post-112614"]/div[1]/h1/text()')

In [2]: print(title)
[<Selector xpath='//*[@id="post-112614"]/div[1]/h1/text()' data='为什么 SQL 正在击败 NoSQL,数据的未来是什么?'>]

In [3]: print(title.extract())
['为什么 SQL 正在击败 NoSQL,数据的未来是什么?']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • ####获取时间
    我们再来获取一下时间,这段比较长,因为我汇总到了一块,之前是一点一点调试出来的,过程可见下图
create_date = response.xpath('//*[@class="entry-meta-hide-on-mobile"]/text()').extract()[0].strip().replace("·","").strip()
  • 1

strip()是去除头尾指定的字符

  • ####获取标题
    一下代码是我直接复制的xpath路径,但在这里只能提取这一篇文章的数据,因为可以考到id="post-112614",这里只适用于这一篇文章,其它的就不行了,所以我们需要更换xpath选择器
create_date = response.xpath('//*[@id="post-112614"]/div[2]/p/text()').extract()[0].strip().repalce("·","").strip()
  • 1


通过测试,我们发现entry-header这个class是全局唯一的,于是我们可以这样提取

title = response.xpath('//*[@class="entry-header"]/h1/text()').extract()[0]
  • 1
  • ####获取点赞数
praise_nums = response.xpath("//span[contains(@class,'vote-post-up')]/h10/text()").extract()[0]
  • 1

contains:匹配一个属性值中包含的字符串

  • ####获取收藏,此处包含’收藏数’和’收藏’两个字
fav_nums = response.xpath("//span[contains(@class,'bookmark-btn')]/text()").extract()[0].strip()
match_re = re.match('.*(\d+).*',fav_nums)
if match_re:
    #获取收藏数
    fav_nums = int(math_re.group(1))
  • 1
  • 2
  • 3
  • 4
  • 5
  • ####获取评论
comment_nums = response.xpath('//*[@class="entry-meta-hide-on-mobile"]/a[2]/text()').extract()[0].strip()
  • 1
  • ####获取文章所属标签
    在这里涉及去重,因为在文章开头和文末都有评论数,所有会出现重复.如下图红色部分,所以我们用判断去除重复的部分

tag_list = response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()
tag_list = [element for element in tag_list if not element.strip().endswith('评论')]
tag = ','.join(tag_list)
  • 1
  • 2
  • 3

这个过程如下图

- ####获取文章内容

content = response.xpath('//*[@class="entry"]').extract()[0]
  • 1

完整代码

def parse_detail(self, response):
    #获取标题
    #可以用//*[@id="post-112614"]/div[1]/h1/text()获取标签里面的值
    title = response.xpath('//*[@class="entry-header"]/h1/text()').extract()[0]
    # print('title',title)
    # re1_selector = response.xpath('//div[@class="entry_header"]/h1/text()')
    #获取时间
    #获取字符串的话用time.extract()[0].strip().repalce("·","").strip()
    create_date = response.xpath('//*[@class="entry-meta-hide-on-mobile"]/text()').extract()[0].strip().replace("·","").strip()
    #获取点赞数
    praise_nums = response.xpath("//span[contains(@class,'vote-post-up')]/h10/text()").extract()[0]
    #获取收藏,此处包含'收藏数'和'收藏'两个字
    fav_nums = response.xpath("//span[contains(@class,'bookmark-btn')]/text()").extract()[0].strip()
    match_re = re.match('.*?(\d+).*',fav_nums)
    if match_re:
        #获取收藏数
        fav_nums = int(match_re.group(1))
    else:
        fav_nums = 0
    #获取评论数
    comment_nums = response.xpath('//*[@class="entry-meta-hide-on-mobile"]/a[2]/text()').extract()[0].strip()
    match_re = re.match('.*?(\d+).*', comment_nums)
    if match_re:
        # 获取收藏数
        comment_nums = int(match_re.group(1))
    else:
        comment_nums = 0
    #获取文章分类标签
    tag_list = response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()
    tag_list = [element for element in tag_list if not element.strip().endswith('评论')]
    tag = ','.join(tag_list)
    content = response.xpath('//*[@class="entry"]').extract()[0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多