内容简介:近期接了个需求,有一个域名要下线(释放出服务器资源),但是又不希望损失SEO。本文适合已经开始接触scrapy的朋友,可能会帮助到你。大概想了2个思路:
近期接了个需求,有一个域名要下线(释放出服务器资源),但是又不希望损失SEO。
本文适合已经开始接触scrapy的朋友,可能会帮助到你。
问题分析
大概想了2个思路:
-
从内部入手,直接用view层渲染出所有页面。
- 缺点:需要梳理所有的页面,枚举出所有的URL,这个工作量不小。
- 从外部入手,直接抓网站的所有页面和依赖资源下来,静态化到本地。
我选择了后者,虽然要做爬虫,但是这样最容易将URL覆盖完整,工作量也仅仅是开发爬虫自身而已。
技术选型
其实镜像网站这个事情,有很多现成的工具,比如wget就支持递归镜像一个网站到本地文件。
还有一些开源项目,就不一一列举了。
我个人试了一下这些工具,最终还是决定自己来研发,它们真的不是很好用,太不可控了。
框架选择python scrapy,这个框架堪称经典,以前也了解过它的架构,而且 python 语言我还算熟悉,所以就直接入手它了。
制作流程
scrapy上手还是蛮简单的,大家参照 中文版的scrapy文档 自学即可,我一共花了2天时间就基本搞定了爬虫,相信大家也差不多。
下面我仅记录一些特殊问题,解决大家可能碰到的疑惑。
安装依赖
除了安装scrapy框架,我还安装了beautifulsoup4,后者用于解析与修改HTML。
为什么要修改HTML?因为网站依赖了其他域下的js,css文件,需要静态化到本地磁盘,这样就需要修改HTML中的链接地址。
beautifulsoup4可以基于lxml库加速执行,lxml是一个高效解析HTML的C扩展,我们得确保它也被安装。
MIDDLEWARES
scrapy默认会引入N多个中间件,它们被定义为:
这些默认的中间件基本是核心必要功能,不需要我们去关闭。
如果你要关闭,就在settings.py中修改SPIDER_MIDDLEWARES和DOWNLOADER_MIDDLEWARES,将对应的中间件设置为None即可关闭。
parse函数
我们发起的request会指定回调parse函数,我们可以在parse函数中提取页面信息为item,也可以产生新的request请求。
parse函数应该是一个迭代器,它应该用yield返回下面任意一种东西,scrapy会持续迭代直到没有更多东西被yield:
- yield要发起的后续request
- yield要投递给pipeline的item
有一个比较好用的功能,就是request可以配置meta保存一些上下文信息,当parse回调时可以从response中取出meta信息恢复上下文,这样我们就很容易知道当时为何要发起这个request。
链接去重
scrapy默认会在内存中去重抓过的链接,链接会被签名为整形保存。
我在使用scrapy的过程中发现,有的URL始终没有被抓取下来,而且scapy日志也没有对应的报错信息,URL像是凭空消失了一样。
网上碰到类似问题的人不在少数,没有搜到正确答案。
我直接跟了scrapy源码,最后定位了原因:因为scrapy默认将待抓URL存储在一个LIFO队列中,意思就是last in first out,所以当有源源不断的后链进入LIFO时,较老的URL始终无法弹出队列,无法得到及时抓取。(if you find scrapy lost urls and there’s no error logs, you need to change the crawling queue type from LIFO to FIFO in settings.py, this may solve your problem)
解决这个问题只需要在settings.py中配置一下队列类型为FIFO(first in first out)即可:
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeues.FifoMemoryQueue'
页面修改
scrapy自带了一些HTML的选择器,可以很方便的找到想要的DOM节点。
但是scrapy不支持修改DOM,所以我用了beautifulsoup4这个经典的类库。
beautifulsoup4也支持css选择器,并且可以直接对DOM做修改,使用起来很方便。
思路方面
因为我要镜像某个域名的所有页面,所以我在follow后链的时候,除了下载js和css允许离开本域,其他的后链则要求必须属于本域,否则不会继续follow下载。
当我从HTML提取外链其他域名的js与css的时候,会进行URL链接改写。比如HTML中有一个外链<script src=”http://www.b.com/xx/yy.js”>,那么我下载后会保存在磁盘的$webroot/www.b.com/xx/yy.js中,并且将HTML中的链接改写为:<script src=”/www.b.com/xx/yy.js”>。
另外,对于类似/xx/yy这样没有文件后缀的URL,我会把内容保存在磁盘的/xx/yy/index.html中。
本域下的图片我也会下载,其他域(包括外链与CDN上的图片)的图片我会保留原始链接。
关于HTML改写的思路大概就是这些。
持久化
scrapy支持持久化抓取状态,我没有用到,大家可以根据官方文档试验一下。
文档: https://doc.scrapy.org/en/latest/topics/jobs.html
代码demo
在github我放了一份代码,大家可以简单参考: https://github.com/owenliang/scrapy
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Nginx 通用网站镜像教程(适用于动态网站与静态网站)
- 那些你用得上的镜像网站
- KVM镜像制作及挂载镜像文件
- 查看Docker镜像仓库中镜像的所有标签
- Vagrant 使用国内镜像安装插件和 box 镜像
- 不要轻易使用 Alpine 镜像来构建 Docker 镜像,有坑!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数字时代的营销战略
曹虎、王赛、乔林、【美】艾拉·考夫曼 / 机械工业出版社 / 2017-1 / 99.00元
菲利普•科特勒说,市场比市场营销变得更快(Market changes faster than Marketing),在这个变革的时代,从硅谷、波士顿到北京、上海、深圳,我们正在重新定义公司,重新定义组织,重新定义战略;同样地,营销亦需要重新定义。 从本质上讲,营销战略只有两个时代:实体时代与比特时代,也可称为工业时代与数字时代。从5年前开始,第二个时代正在向未来20年展开画卷,数字创新型企......一起来看看 《数字时代的营销战略》 这本书的介绍吧!