AI教程网 - 未来以来,拥抱AI;新手入门,从AI教程网开始......

Scrapy Css

Scrapy教程 AI君 141℃ 0评论

首先我们来说说css选择器,和scrapy相关的函数就这么三个而已:response.css(“css表达式”)、extract()、extract_first()。有变化的就是:css表达式的写法,这里我们就列举一些常见的表达式,虽然不能囊括100%的爬取任务,但可以很负责的说,至少可以囊括90%的爬取,这里小编会把常见的给诸位列举哈,诸位见类似的便可直接依葫芦画瓢使用了。按照HTML标签的结构可以分为:标签属性值提取、标签内容提取,我们分别介绍对应的情况;

一、标签属性值的提取

1、href的值URL的提取:这是最常见的,我们要进入下一页、或是打开内容页……都少不了URL值,如下面这段HTML,我们来提取一下里面的URL

<ol class="page-navigator">
  <li class="current"><a href="http://lab.scrapyd.cn/page/1/">1</a></li>
  <li><a href="http://lab.scrapyd.cn/page/2/">2</a></li>
  <li><a href="http://lab.scrapyd.cn/page/3/">3</a></li>
  <li><a href="http://lab.scrapyd.cn/page/4/">4</a></li>
</ol>

这其实是我们爬虫实验室的分页,如果我们要爬取下一页,我们该如何提取URL呢?提取属性我们是用:“标签名::attr(属性名)”,比如我们要提取url表达式就是:a::attr(href),要提取图片地址的表达式就是:img::attr(src)……以此类推,好了知道scrapy给我们提供的提取变了的工具,那我们就可以提取上面的URL了,有多种方式,首先我们可以直接:

response.css("a::attr(href)")

然后,我们调试一下,看是不是我们想要的结果,cmd输入:

scrapy shell lab.scrapy.cn

然后我们发现结果并非是我们想要的分页URL,而是页面中所有的URL:

Out[3]:
['http://lab.scrapyd.cn/',
 'http://lab.scrapyd.cn/archives/57.html',
 'http://lab.scrapyd.cn/tag/%E8%89%BA%E6%9C%AF/',
 'http://lab.scrapyd.cn/tag/%E5%90%8D%E7%94%BB/',
……
 'http://lab.scrapyd.cn/page/1/',
 'http://lab.scrapyd.cn/page/2/',
……
 'http://lab.scrapyd.cn/page/6/',
 'http://lab.scrapyd.cn/page/2/',
 'http://lab.scrapyd.cn/tag/%E4%BA%BA%E7%94%9F/',
……
 'http://lab.scrapyd.cn/tag/%E5%90%8D%E7%94%BB/',
 'http://lab.scrapyd.cn/tag/%E7%94%9F%E6%B4%BB/',
……
 'http://lab.scrapyd.cn/']

这当然不是我们想要的,我们想要的只是分页的URL,那这要怎么办?那我们就需要限定一下我们URL的范围,最好的方法就是找到我们要提取目标最近的class或是id,可以看到这段代码中有个class=”page-navigator”,那我们就可以这样来写:

response.css(".page-navigator a::attr(href)").extract()

当这样限定之后,我们发现这就成功提取了我们想要的URL,灰常的完美!随便解释哈上面的:.page-navigator,其中点代表class选择器,如果代码中是:id=“page-navigator”,那我们这里就要写成:“#page-navigator”,大家如果不清楚可以去这里看看:https://www.runoob.com/css/css-id-class.html;
再来一个提取标签属性的栗子,最常见的就是我们的图片地址,也就是要提取图片的src值,如下面网页:

<article class="post" itemscope="" itemtype="http://schema.org/BlogPosting">
        <h1 class="post-title" itemprop="name headline"><a itemprop="url" href="http://lab.scrapyd.cn/archives/57.html">中国传世名画</a></h1>
        <div class="post-content" itemprop="articleBody">
            <p>看官,此页面只为爬虫练习使用,都是残卷,若喜欢可以去找点高清版!</p>
            <p><img src="http://www.ainoob.cn/wp-content/images/201903/3875934880.jpg" alt="1.jpg" title="1.jpg"></p>
                        <p><img src="http://www.ainoob.cn/wp-content/images/201903/2269613152.jpg" alt="2.jpg" title="2.jpg"></p>
            <p><img src="http://www.ainoob.cn/wp-content/images/201903/2360992798.jpg" alt="3.jpg" title="3.jpg"></p>
            <p><img src="http://www.ainoob.cn/wp-content/images/201903/2239103416.jpg" alt="4.jpg" title="4.jpg"></p>
            <p><img src="http://www.ainoob.cn/wp-content/images/201903/4145232684.jpg" alt="5.jpg" title="5.jpg"></p>        
        </div>
        <p itemprop="keywords" class="tags">标签: <a href="http://lab.scrapyd.cn/tag/%E8%89%BA%E6%9C%AF/">艺术</a>, <a href="http://lab.scrapyd.cn/tag/%E5%90%8D%E7%94%BB/">名画</a></p>
    </article>

这个页面是我们爬虫实验室:http://lab.scrapyd.cn/archives/57.html的文章,我们要提取里面图片的地址供scrapy下载,有上面的基础就很简单了:首先找到隔img最近的class或id,可以看到有个:class=”post-content”,于是我们可以这样写表达式:

response.css(".post-content img::attr(src)").extract()

调试的话自己试哈,经过这个表达式:”.post-content img::attr(src),可以看到已经成功提取出来:

Out[2]:
['http://www.ainoob.cn/wp-content/images/201903/3875934880.jpg',
 'http://www.ainoob.cn/wp-content/images/201903/2269613152.jpg',
 'http://www.ainoob.cn/wp-content/images/201903/2360992798.jpg',
 'http://www.ainoob.cn/wp-content/images/201903/2239103416.jpg',
 'http://www.ainoob.cn/wp-content/images/201903/4145232684.jpg']

好了上面便是提取标签属性的方法,利用的就是:标签名::attr(属性名),关键点就是如何缩小范围!

二、标签内容的提取

设么是标签内容,比如:

<p>scrapy中文网</p>

<div>scrapy中文网:www.scrapyd.cn</div>

<h1>scrapy实验室:lab.scrapyd.cn</h1>

<title>scrapy中文网</title>

上面标签:p、div、h1里面的文字便是标签内容,那我们要如何提取呢?用到了scrapy给我提供的这么一个方法:“::text”,比如要提取上面p标签里面的内容,我们可以这样:

response.css("p::text").extract()

那接下来我们就演示哈如何提取scrapy中文网:http://www.scrapd.cn的title:

<html lang="zh-CN">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Scrapy 中文网</title>
……

提取方式:

 response.css("title::text").extract()

上面的这个栗子灰常简单,应为tittle标签是页面唯一的标签,所以在title前不用加什么限制,当你发现标签不唯一的时候,我们就需要缩小范围,原理和上面标签属性提取一样,要么找最近的class、要么找最近的id,然后最终缩小提取访问,这样就能让提取很准确,如下面这个例子:

<div class="left">
  scrapy中文网左边
</div>

<div class="center">
  scrapy中文网中部
</div>

<div class="right">
  scrapy中文网右侧
</div>

如果我们要提取第二个div里面的内容,我们肯定不能这样:

 response.css("div::text").extract()

如果这样提取的话,我们肯定得不到正确的结果,我们还需要限制哈范围,找到最近的class=“center”,最终表达式如下:

response.css(".center::text").extract()

这样的话就能正确提取我们想要的内容;下面我们再介绍一个最常用的提取方式:含有嵌套标签文字的提取,HTML如下:

<div class="post-content" itemprop="articleBody">
  <p>如果你因失去了太阳而流泪,那么你也将失去群星了。 <br>
    If you shed tears when you miss the sun, you also miss the stars. 
   </p>
   <p>
    <a href="http://www.scrapyd.cn">scrapy中文网(</a><a href="http://www.scrapyd.cn">http://www.scrapyd.cn</a>)整理 
   </p>       
 </div>

如果我们要提取class=“post-content”里面的所有文字,我们需要怎么办呢?显然上面的知识无法做到。这段文字是scrapy实验室:http://lab.scrapyd.cn/archives/28.html 里的文章,诸位可以scrapy shell进行验证结果,可以记住用下面的方式:

response.css(".post-content *::text").extract()

可以看到,“::tex“t前面有个“*”号,这是一个小技巧,一般人我都告诉他,学着点!

转载请注明:www.ainoob.cn » Scrapy Css

喜欢 (0)or分享 (0)

您必须 登录 才能发表评论!