Scrapy根据XPATH解析页面内容、下载为json格式文件、抓取列表页等的简单示例

作者: admin 分类: Scrapy 发布时间: 2019-07-20 00:45  阅读: 276 views

Scrapy爬虫在抓取的时候,主要是根据页面元素结构进行解析。有多种方式,如:Jsoup、正则、xpath等解析。或者selenium自动化工具等。

Xpath

XPath 是一门在 XML 文档中查找信息的语言。XPath 使用路径表达式在 XML 文档中进行导航。XPath 包含一个标准函数库。XPath 是 XSLT 中的主要元素
。XPath 是一个 W3C 标准

示例xml格式内容
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>
<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>
</bookstore>

常用的语法如下
nodename 选取此节点的所有子节点。

/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。

如下

bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性。

谓语(Predicates)

bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

选取未知节点

* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title[@*] 选取所有带有属性的 title 元素。
选取若干路径
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
//title | //price 选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

Scrapy在MAC环境的安装、Scrapy引擎基本介绍、简单的创建命令功能实践

将上文中的parse方法进行修改

    def parse(self, response):
#         filename = "676.html"
#         open(filename,'wb').write(response.body)
        title = response.xpath('//*[@id="main"]/article/h1/text()')
        context = response.xpath('//*[@id="main"]/article/div[2]/text()')
        print(title)
        print(context)
        pass

运行项目可以看到

[<Selector xpath='//*[@id="main"]/article/h1/text()' data='Oracle使用正则表达式REGEXP_REPLACE替换xml格式文档中的数据'>]
说明获取成功

正文内容获取的几种方式

  • 获取data正文
    >context = response.xpath(‘//*[@id=”main”]/article/div[2]/text()).extract()
  • 获取data正文,去除换行、空格等信息
    >context = response.xpath(‘normalize-space(//*[@id=”main”]/article/div[2]/text())’).extract()
  • 获取data正文下的所有节点的所有文本信息
    >context = response.xpath(‘//*[@id=”main”]/article/div[2]’).xpath(‘string()’).extract()
  • 获取data正文下的所有节点的所有文本信息去掉空格、换行
    >context = response.xpath(‘//*[@id=”main”]/article/div[2]’).xpath(‘normalize-space(string())’).extract()

下面这种方式可以满足简单需求,将数据保存到本地为json格式的数据

其中关于yield的用法说明,请参考,我说不好
https://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/

引用item对象时需要导入包
from Zhizhu.items import ZhizhuItem

class DeathearthSpider(scrapy.Spider):
    name = 'deathearth'                       #爬虫的唯一识别名称,不同爬虫需要不同名字
    allowed_domains = ['xxx.cn']      #爬虫搜索的域名范围,只会在该域名下
    start_urls = ['http://xxx.cn/676.html'] #爬虫的url元组/列表。从这里开始抓取,从这里生成子urls

    #解析方法,每个url下载后将被调用,主要解析网页提取数据,生存下一级url
    def parse(self, response):
        #通过xpath获取html元素
        title = response.xpath('normalize-space(//*[@id="main"]/article/h1/text())').extract()
        context = response.xpath('//*[@id="main"]/article/div[2]').xpath('normalize-space(string())').extract()

        item = ZhizhuItem();
        item['title'] = title
        item['info'] = context       
        yield item
scrapy crawl deathearth -o items.json

以下这种写法是获取页面中的所有目标url进行提取

class DeathearthSpider(scrapy.Spider):
    name='deathearth'
    allowed_domains=['xxx.cn']
    start_urls= ['http://xxx.cn']

    def parse(self,response):
        #获取当前页面下列表中的所有文章连接【评论、分类链接排除】. 具体看xpath详细用法
        for href in response.xpath('//*[@id="main"]/div/div/article/header/h1/a/@href').extract():
            #url = response.urljoin(response.url,href)  #当遇到相对路径时,使用该方法拼接
            print('这绝对路径的url',href)
            #对href产生一个请求,并回调parse_dir_contents解析每个内容,self必须加,否则找不到
            yield scrapy.Request(href, callback=self.parse_dir_contents)

    def parse_dir_contents(self,response):
        title = response.xpath('normalize-space(//*[@id="main"]/article/h1/text())').extract()
        print()
        print(title)

其中response.xpath(‘//*[@id=”main”]/div/div/article/header/h1/a/@href’)获取到的数据是

[<Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/554.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/549.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/540.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/524.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/515.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/510.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/499.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/493.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/486.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/480.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/462.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/455.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/450.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/434.html'>, <Selector xpath='//*[@id="main"]/div/div/article/header/h1/a/@href' data='http://xxx.cn/422.html'>]

以下是输出结果,说明Scrapy应该是分段调度

2019-04-19 16:17:09 [scrapy.core.engine] INFO: Spider opened
2019-04-19 16:17:09 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-04-19 16:17:09 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2019-04-19 16:17:09 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/robots.txt> (referer: None)
2019-04-19 16:17:09 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET http://xxx.cn/page/2> from <GET http://xxx.cn/page/2/>
2019-04-19 16:17:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/page/2> (referer: None)
2019-04-19 16:17:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/554.html> (referer: http://xxx.cn/page/2)
['利用linux命令行grep|awk在mac本上分析wordpress.log访问日志']
2019-04-19 16:17:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/434.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/450.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/480.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/486.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/455.html> (referer: http://xxx.cn/page/2)
['程序猿思维的转变以及对设计思路的影响']
['交换IT技术类博客|个站的友情链接']
['杭州积分落户相关材料纳税证明如何下载以及流程']
2019-04-19 16:17:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/422.html> (referer: http://xxx.cn/page/2)
['WormHole是一个简单、易用的api管理平台,支持dubbo服务调用']
['环境搭建-Eclipse安装Spring-Tool-Sutite插件并创建简单的SpringBoot项目']
2019-04-19 16:17:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/462.html> (referer: http://xxx.cn/page/2)
['程序猿的SEO学习之路|对这段时间的一个整理及重新认识']
['SpringBoot2.1.3集成velocity2.0的环境配置及过程记录']
2019-04-19 16:17:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/515.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/510.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/524.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/493.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/540.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/549.html> (referer: http://xxx.cn/page/2)
2019-04-19 16:17:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/499.html> (referer: http://xxx.cn/page/2)
['WormHole网关平台多环境配置使用说明']
['WormHole网关平台关于回调接口使用的说明']
['WormHole网关平台的错误码一览说明']
['WormHole网关平台关于C端对接以及签名的说明']
['书籍推荐:心里学基础课系列教材《普通心理学》第四版/彭冉龄']
['SpringBoot改造异常:Invalid bean definition with name ‘mvcUriComponentsContributor’ defined in class path resource']
['WormHole网关平台API管理台操作说明']
2019-04-19 16:17:14 [scrapy.core.engine] INFO: Closing spider (finished)

从首页的分页列表进行查询,非上下翻页的结构。 这里感觉直接查看分页url规则,直接进行固定页数的查询解析更方便
页面结构如下,当页面点击5页时,才会出现新的分页连接。

<nav style="float:right">
<ul class="pagination">
<li><a href="http://xxx.cn/">1</a></li>
<li><a href="http://xxx.cn/page/2">2</a></li>
<li class="active"><a href="http://xxx.cn/page/3">3<span class="sr-only">(current)</span></a></li>
<li><a href="http://xxx.cn/page/4">4</a></li>
<li><a href="http://xxx.cn/page/5">5</a></li>
<li><a href="http://xxx.cn/page/6">6</a></li>
<li><a href="http://xxx.cn/page/7">7</a></li>
</ul>
</nav>

通过定位html进行解析

#通过定位html进行解析
class DeathearthSpider(scrapy.Spider):
    name='deathearth'
    allowed_domains=['xxx.cn']
    start_urls= ['http://xxx.cn']

    def parse(self,response):
        for page in response.xpath('//*[@id="main"]/div/div/nav/ul/li/a/@href').extract():
            yield scrapy.Request(page, callback=self.parse_list)

    def parse_list(self,response):
        for href in response.xpath('//*[@id="main"]/div/div/article/header/h1/a/@href').extract():
            yield scrapy.Request(href, callback=self.parse_dir_contents)

    def parse_dir_contents(self,response):
        title = response.xpath('normalize-space(//*[@id="main"]/article/h1/text())').extract()
        print()
        print(title)

通过定死分页大小,进行查询

#通过定死分页大小,进行查询
class ManypageSpider(scrapy.Spider):
    name = 'manyPage'
    allowed_domains = ['xxx.cn']
    start_urls = ['http://xxx.cn/page/1/']

    count=0
    common_url = 'http://xxx.cn/page/'
    size = [1,2,3,4,5]
    #根据连接形式 http://xxx.cn/page/*, 查找固定页面
    def parse(self, response):
        for index in self.size:
            #字符串 和 数字不能直接相加
            url = self.common_url+str(index)
            yield scrapy.Request(url,callback=self.find_all_page)
        pass
    #循环每一页的页面链接
    def find_all_page(self,response):
        for url in response.xpath('//*[@id="main"]/div/div/article/header/h1/a/@href').extract():
            yield scrapy.Request(url,callback=self.parseContext)
        pass
    #解析页面内容
    def parseContext(self,response):
        title = response.xpath('//*[@id="main"]/article/h1/text()').extract()
        print(title)
2019-04-19 17:16:05 [scrapy.core.engine] INFO: Spider opened
2019-04-19 17:16:05 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-04-19 17:16:05 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2019-04-19 17:16:06 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/robots.txt> (referer: None)
2019-04-19 17:16:06 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/page/1/> (referer: None)
2019-04-19 17:16:08 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/page/5> (referer: http://xxx.cn/page/1/)
2019-04-19 17:16:08 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/page/3> (referer: http://xxx.cn/page/1/)
2019-04-19 17:16:08 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/page/2> (referer: http://xxx.cn/page/1/)
2019-04-19 17:16:08 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/page/1> (referer: http://xxx.cn/page/1/)
2019-04-19 17:16:08 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/page/4> (referer: http://xxx.cn/page/1/)
2019-04-19 17:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/480.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/486.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/434.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/235.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/422.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/455.html> (referer: http://xxx.cn/page/2)
['杭州积分落户相关材料纳税证明如何下载以及流程']
['WormHole是一个简单、易用的api管理平台,支持dubbo服务调用']
['程序猿思维的转变以及对设计思路的影响']
2019-04-19 17:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/462.html> (referer: http://xxx.cn/page/2)
['巧妙使用位运算(&和|)来处理数据状态,统一快速又方便']
['程序猿的SEO学习之路|对这段时间的一个整理及重新认识']
2019-04-19 17:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/450.html> (referer: http://xxx.cn/page/2)
['环境搭建-Eclipse安装Spring-Tool-Sutite插件并创建简单的SpringBoot项目']
['SpringBoot2.1.3集成velocity2.0的环境配置及过程记录']
['交换IT技术类博客|个站的友情链接']
2019-04-19 17:16:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/515.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/510.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/493.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/524.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/549.html> (referer: http://xxx.cn/page/2)
2019-04-19 17:16:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/540.html> (referer: http://xxx.cn/page/2)
['WormHole网关平台多环境配置使用说明']
['WormHole网关平台关于回调接口使用的说明']
['WormHole网关平台关于C端对接以及签名的说明']
['WormHole网关平台的错误码一览说明']
2019-04-19 17:16:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/499.html> (referer: http://xxx.cn/page/2)
['SpringBoot改造异常:Invalid bean definition with name ‘mvcUriComponentsContributor’ defined in class path resource']
2019-04-19 17:16:12 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/554.html> (referer: http://xxx.cn/page/2)
['书籍推荐:心里学基础课系列教材《普通心理学》第四版/彭冉龄']
['WormHole网关平台API管理台操作说明']
['利用linux命令行grep|awk在mac本上分析wordpress.log访问日志']
2019-04-19 17:16:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/249.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/252.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/259.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/245.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/256.html> (referer: http://xxx.cn/page/4)
['为什么业余时间要做这样一个在线考核系统']
['如何给一个类后台管理系统选择页面搭建工具?']
2019-04-19 17:16:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/264.html> (referer: http://xxx.cn/page/4)
['阿里云 linux – 当前在xxx.xx.xxx.xx 服务器上搭建在线考核项目']
2019-04-19 17:16:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/300.html> (referer: http://xxx.cn/page/4)
['吾终日三省吾身,昨日幡然醒悟和别人的差距,原来这么大…']
['在阿里云linux系统下安装jenkins的deb版本时遇到的问题']
['如何对行进中的项目进行有效的版本控制?']
2019-04-19 17:16:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/239.html> (referer: http://xxx.cn/page/4)
['书籍推荐:淘宝技术的发展与故事阐述《淘宝技术这十年》']
['利用httpclient制作网关层接口的快速测试界面,仿postman测试工具']
2019-04-19 17:16:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/310.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/314.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/318.html> (referer: http://xxx.cn/page/4)
['JAVA环境搭建后的必备良器,阿里代码规范检查工具']
['如何在工作和生活中压榨时间,去做项目设计和数据分析?']
2019-04-19 17:16:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/304.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/320.html> (referer: http://xxx.cn/page/4)
['环境搭建之Mac下安装SplunkEnterprise日志服务程序/SplunkForward通用转发器部署客户端']
2019-04-19 17:16:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/333.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/323.html> (referer: http://xxx.cn/page/4)
2019-04-19 17:16:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/636.html> (referer: http://xxx.cn/page/1)
['环境搭建之在linux系统下安装nexus 3.11版本的过程记录']
['环境搭建之日志搜集/采集服务系统对比(logtail/hadoop/elk/splunk/appender)']
['环境搭建之linux下ELK搭建好之后配置sentinl插件,进行邮件告警']
['(ElasticSearch+LogStash+Kibana)ELK搭建在Mac/Linux系统上6.4.2版本']
['通过curl或者http请求对elasticsearch中的数据进行增删改查']
2019-04-19 17:16:17 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/649.html> (referer: http://xxx.cn/page/1)
2019-04-19 17:16:17 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/645.html> (referer: http://xxx.cn/page/1)
['通过一张图来分析下背后的故事,python程序猿?']
['linux常用命令行在mac本上做基础练习与记录']
2019-04-19 17:16:18 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/651.html> (referer: http://xxx.cn/page/1)
2019-04-19 17:16:18 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/654.html> (referer: http://xxx.cn/page/1)
2019-04-19 17:16:18 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/656.html> (referer: http://xxx.cn/page/1)
['java使用transportClient连接elasticsearch并做接口实现增删改查ES6.4.3版本']
['Oracle数据库中怎么查询锁表进程以及杀掉进程']
2019-04-19 17:16:18 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/664.html> (referer: http://xxx.cn/page/1)
2019-04-19 17:16:18 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/660.html> (referer: http://xxx.cn/page/1)
['在mac环境下记录Python的学习笔记之基本介绍']
2019-04-19 17:16:18 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/666.html> (referer: http://xxx.cn/page/1)
['在mac环境下记录Python的学习笔记之运算符+条件语句']
['在mac环境下记录Python的学习笔记之基础语法+变量类型']
['在mac环境下记录Python的学习笔记之导入+模块']
2019-04-19 17:16:19 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/668.html> (referer: http://xxx.cn/page/1)
2019-04-19 17:16:19 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/671.html> (referer: http://xxx.cn/page/1)
['在mac环境下记录Python的学习笔记之函数+异常']
2019-04-19 17:16:19 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/676.html> (referer: http://xxx.cn/page/1)
['Mac系统安装python3.7.3并安装Scrapy爬虫框架']
2019-04-19 17:16:19 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/679.html> (referer: http://xxx.cn/page/1)
['Oracle使用正则表达式REGEXP_REPLACE替换xml格式文档中的数据']
2019-04-19 17:16:20 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/355.html> (referer: http://xxx.cn/page/3)
2019-04-19 17:16:20 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/681.html> (referer: http://xxx.cn/page/1)
2019-04-19 17:16:20 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/683.html> (referer: http://xxx.cn/page/1)
['elasticsearch6.4.2安装x-pack安全认证后,java如何使用transportclient连接/resthighlevelclient连接']
['ELK环境搭建之filebeat根据不同的监控日志文件建立不同的索引']
['JAVA程序多线程批量初始化ES数据时产生的异常问题以及解惑记录']
2019-04-19 17:16:20 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/360.html> (referer: http://xxx.cn/page/3)
['使用富文本编辑器保存数据后进行fastjson格式转换异常及序列化处理']
['好文推荐:走向癫疯——大日本帝国的崛起与崩溃']
2019-04-19 17:16:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/362.html> (referer: http://xxx.cn/page/3)
2019-04-19 17:16:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/365.html> (referer: http://xxx.cn/page/3)
2019-04-19 17:16:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/370.html> (referer: http://xxx.cn/page/3)
['java用poi包导入excel时出现poi . Characters larger than 4 bytes are not supported: byte 0x88 implies a']
['Java连接ElasticSearch(low-level-rest-client)的配置和数据的增加/查询']
['脚本清理最近X日之前的ELK日志文件,优化磁盘空间']
2019-04-19 17:16:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/375.html> (referer: http://xxx.cn/page/3)
2019-04-19 17:16:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/382.html> (referer: http://xxx.cn/page/3)
2019-04-19 17:16:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/380.html> (referer: http://xxx.cn/page/3)
2019-04-19 17:16:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/384.html> (referer: http://xxx.cn/page/3)
['使用kibana的开发工具console做一些elasticsearch的基本查询和设置']
['利用fastjson快速过滤对象中的无效属性及统一格式化时间']
['linux系统下利用curl命令对网站资源进行操作和解析']
['用Java代码实现监控zookeeper节点信息的变化以及遍历节点']
2019-04-19 17:16:22 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/388.html> (referer: http://xxx.cn/page/3)
['作为一个JAVA技术人员的2018年终工作总结']
2019-04-19 17:16:23 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/391.html> (referer: http://xxx.cn/page/3)
2019-04-19 17:16:23 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/399.html> (referer: http://xxx.cn/page/3)
['通过添加索引提高多条件查询mysql单表大量数据的测试']
2019-04-19 17:16:23 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/407.html> (referer: http://xxx.cn/page/3)
['ORACLE数据库中怎么用pl/sql实现九九乘法表的输出']
2019-04-19 17:16:23 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/419.html> (referer: http://xxx.cn/page/3)
['ELK搭建环境之配置logstash监听文件并利用grok插件进行切割利于统计']
2019-04-19 17:16:23 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/173.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:23 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/175.html> (referer: http://xxx.cn/page/5)
['ORACLE 多行转一行函数WMSYS.WM_CONCAT和LISTAGG的使用']
2019-04-19 17:16:23 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/416.html> (referer: http://xxx.cn/page/3)
['30岁油腻大叔程序猿是怎么在新的工作生活中存活下来的']
['对于开发来说,一个好团队和差团队的区别在哪里?']
2019-04-19 17:16:23 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/179.html> (referer: http://xxx.cn/page/5)
['docker学习笔记 Mac安装docker(Version18.09.1)及简单应用']
['是生活选择了我们,还是我们选择了生活?']
2019-04-19 17:16:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/191.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/194.html> (referer: http://xxx.cn/page/5)
['对于在线考核这样的功能,是哪些用户群体的需求呢?']
2019-04-19 17:16:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/208.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/204.html> (referer: http://xxx.cn/page/5)
['SpringMVC+Spring项目使用AOP处理异常失效的问题']
2019-04-19 17:16:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/212.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/218.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/180.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/187.html> (referer: http://xxx.cn/page/5)
['作为新人入职新公司三月的工作总结']
['网关设计基本流程以及签名算法处理、乱码处理方式']
['一份很精彩的技术面试评价,懂的人自然懂']
['项目中如何使用自定义异常类来实现错误码和错误信息的规范输出?']
['项目重构过程中碰到的一些严重的问题整理']
['为什么要开始做这样一个在线考核系统?']
2019-04-19 17:16:26 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/227.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:26 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/229.html> (referer: http://xxx.cn/page/5)
2019-04-19 17:16:26 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://xxx.cn/231.html> (referer: http://xxx.cn/page/5)
['使用AOP拦截controller层方法时,通过监控方法上的注解(@Annotation)达到业务上的隔离或验证']
['请认真的问下自己,你已经做好创业的准备了么?']
['首页访问量大的情况下,做一级、二级缓存策略以及一些使用规则']
2019-04-19 17:16:26 [scrapy.core.engine] INFO: Closing spider (finished)

当然如果分页页数超过了实际页数,会返回以下信息

2019-04-19 17:19:38 [scrapy.spidermiddlewares.httperror] INFO: Ignoring response <404 http://xxx.cn/page/54>: HTTP status code is not handled or not allowed
2019-04-19 17:19:38 [scrapy.spidermiddlewares.httperror] INFO: Ignoring response <404 http://xxx.cn/page/44>: HTTP status code is not handled or not allowed

根据点击下一页获取某度列表信息

# -*- coding: utf-8 -*-
import scrapy

class NextpageSpider(scrapy.Spider):
    name = 'nextPage'
    allowed_domains = ['xxx.cn']
    start_urls = ['https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=2&tn=baiduhome_pg&wd=request&rsv_spt=1&oq=Request%2520url%2520must%2520be%2520str%2520or%2520unicode%252C%2520got%2520%2526lt%253Bs%253A%2526%252339%253B%2520%2526lt%253B%2520type(url)&rsv_pq=9d3dcc8b00009c8c&rsv_t=31f3EmONN8BSOoBdpAnMFyIMS6WXT5VOuvrUPXRF4GixmQ7x%2BYVGrxoXPCt%2Fgkf5JvzY&rqlang=cn&rsv_enter=0&inputT=897&rsv_sug3=13&rsv_sug1=6&rsv_sug7=100&bs=Request%20url%20must%20be%20str%20or%20unicode%2C%20got%20%25s%3A%27%20%25%20type(url)']

    #根据连接形式 http://xxx.cn/page/*, 查找固定页面
    def parse(self, response):
        nextPage = response.xpath('//*[@id="page"]/a[11]/@href').extract()
        yield scrapy.Request(nextPage,callback=self.parseContext)
        pass

    #解析页面内容
    def parseContext(self,response):
        title = response.xpath('//*[@id="content_left"]/div/h3/a/@href').extract()
        print(title)

碰到第一个基本的反爬措施 robots.txt协议,指明了哪些user-agent可以爬,哪些不能爬,还有目录、路径等的指定
控制台输出以下信息

2019-04-19 19:12:19 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.baidu.com/robots.txt> (referer: None)
2019-04-19 19:12:19 [scrapy.downloadermiddlewares.robotstxt] DEBUG: Forbidden by robots.txt: <GET https://www.baidu.com/s?request>

在看看百度的robots.txt协议, 地址栏键入

"view-source:https://www.baidu.com/robots.txt"

User-agent: Baiduspider
Disallow: /baidu
Disallow: /s?
Disallow: /ulink?
Disallow: /link?
Disallow: /home/news/data/

........

User-agent: *
Disallow: /

可以看到除了一些主流蜘蛛被限制不能爬取特定目录之外。其他的user-agent都禁止了。这是给良心爬虫开发的一个规则,告诉你哪个能爬,哪个不能爬。但是很多蜘蛛还是违背了这个协议,直接爬取。大站一般都有其他的防御机制,小站技术能力薄弱,只能任人宰割。大规模的蜘蛛爬取操作可能会冲垮小站的服务器。版权意识、原创标记的意识也就慢慢在站长们心中树立了起来了。当然,爬取信息进行传播有好也有坏,主要看爬的人是什么目的。

言归正传,这里如果想爬取某度,就先把scrapy的规则调整下。项目下的settings.py文件中找到
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
修改为false就可以了
# -*- coding: utf-8 -*-
import scrapy

class NextpageSpider(scrapy.Spider):
    name = 'nextPage'
    allowed_domains = ['www.baidu.com']
    start_urls = ['https://www.baidu.com/s?wd=request&rsv_spt=1&rsv_iqid=0xbed13e81000143d5&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=&tn=baiduhome_pg&ch=&rsv_enter=1&inputT=2774']

    #根据连接形式 http://xxx.cn/page/*, 查找固定页面
    def parse(self, response):
        nextPage = response.xpath('//*[@id="page"]/a[10]/@href').extract()
        if nextPage is not None:
            newUlr = response.urljoin(nextPage)
        else:
            pass
        yield scrapy.Request(newUlr,callback=self.parseContext)

    #解析页面内容
    def parseContext(self,response):
        print(response)
        print(response.xpath('//div'))
        for title in response.xpath('//*[@id="21"]/h3/a').extract():
            print('title===='+str(title))

scrapy 抓取https的处理方式
https://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/tutorial.html

其他后续补充


   原创文章,转载请标明本文链接: Scrapy根据XPATH解析页面内容、下载为json格式文件、抓取列表页等的简单示例

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

更多阅读