- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章5分钟快速掌握scrapy爬虫框架由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
1. scrapy简介 。
scrapy是基于事件驱动的Twisted框架下用纯python写的爬虫框架。很早之前就开始用scrapy来爬取网络上的图片和文本信息,一直没有把细节记录下来。这段时间,因为工作需要又重拾scrapy爬虫,本文和大家分享下,包你一用就会, 欢迎交流.
1.1 scrapy框架 。
scrapy框架包括5个主要的组件和2个中间件Hook.
从上可知,我们只要实现SPIDERS(要爬什么网站,怎么解析)和ITEM PIPELINES(如何处理解析后的内容)就可以了。其他的都是有框架帮你完成了。(图片来自网络,如果侵权联系必删) 。
1.2 scrapy数据流 。
我们再详细看下组件之间的数据流,会更清楚框架的内部运作。(图片来自网络,如果侵权联系必删) 。
第1步到第8步,一个请求终于完成了。是不是觉得很多余?ENGIINE夹在中间当传话筒,能不能直接跳过?可以考虑跳过了会怎么样.
这里分析一下 。
2. 基础:XPath 。
写爬虫最重要的是解析网页的内容,这个部分就介绍下通过XPath来解析网页,提取内容.
2.1 HTML节点和属性 。
(图片来自网络,如果侵权联系必删) 。
2.2 解析语法 。
一个例子 。
response.xpath('//div[@class="taglist"]/ul//li//a//img/@data-original').get_all() 。
# 获取所有class属性(css)为taglist的div, 下一个层ul下的所有li下所有a下所有img标签下data-original属性 。
# data-original这里放的是图片的url地址 。
更多详见 。
http://zvon.org/comp/r/tut-XPath_1.html#Pages~List_of_XPaths 。
3. 安装部署 。
Scrapy 是用纯python编写的,它依赖于几个关键的python包(以及其他包):
# 安装 。
pip install scrapy 。
4. 创建爬虫项目 。
scrapy startproject sexy 。
# 创建一个后的项目目录 。
# sexy 。
# │ scrapy.cfg 。
# │ 。
# └─sexy 。
# │ items.py 。
# │ middlewares.py 。
# │ pipelines.py 。
# │ settings.py 。
# │ __init__.py 。
# │ 。
# ├─spiders 。
# │ │ __init__.py 。
# │ │ 。
# │ └─__pycache__ 。
# └─__pycache__ 。
# 执行 需要到scrapy.cfg同级别的目录执行 。
scrapy crawl sexy 。
从上可知,我们要写的是spiders里的具体的spider类和items.py和pipelines.py(对应的ITEM PIPELINES) 。
5. 开始scrapy爬虫 。
5.1 简单而强大的spider 。
这里实现的功能是从图片网站中下载图片,保存在本地, url做了脱敏。需要注意的点在注释要标明 。
可以看到parse实现的时候没有转发给ITEM PIPELINES,直接处理了。这样简单的可以这么处理,如果业务很复杂,建议交给ITEM PIPELINES。后面会给例子 。
# 目录结果为:spiders/sexy_spider.py 。
import scrapy 。
import os 。
import requests 。
import time 。
def download_from_url(url): 。
response = requests.get(url, stream=True) 。
if response.status_code == requests.codes.ok: 。
return response.content 。
else: 。
print('%s-%s' % (url, response.status_code)) 。
return None 。
class SexySpider(scrapy.Spider): 。
# 如果有多个spider, name要唯一 。
name = 'sexy' 。
allowed_domains = ['uumdfdfnt.94demo.com'] 。
allowed_urls = ['http://uumdfdfnt.94demo.com/'] 。
# 需要爬取的网站url加到start_urls list里 。
start_urls = ['http://uumdfdfnt.94demo.com/tag/dingziku/index.html'] 。
save_path = '/home/sexy/dingziku' 。
def parse(self, response): 。
# 解析网站,获取图片列表 。
img_list = response.xpath('//div[@class="taglist"]/ul//li//a//img/@data-original').getall() 。
time.sleep(1) 。
# 处理图片, 具体业务操作, 可交给items, 见5.2 items例子 。
for img_url in img_list: 。
file_name = img_url.split('/')[-1] 。
content = download_from_url(img_url) 。
if content is not None: 。
with open(os.path.join(self.save_path, file_name), 'wb') as fw: 。
fw.write(content) 。
# 自动下一页(见5.3 自动下一页) 。
next_page = response.xpath('//div[@class="page both"]/ul/a[text()="下一页"]/@href').get() 。
if next_page is not None: 。
next_page = response.urljoin(next_page) 。
yield scrapy.Request(next_page, callback=self.parse) 。
5.2 items和pipline例子 。
这里说明下两个的作用 。
我们来改写下上面的例子 。
import scrapy 。
class SexyItem(scrapy.Item): 。
# define the fields for your item here like: 。
# name = scrapy.Field() 。
img_url = scrapy.Field() 。
import scrapy 。
import os 。
# 导入item 。
from ..items import SexyItem 。
class SexySpider(scrapy.Spider): 。
# 如果有多个spider, name要唯一 。
name = 'sexy' 。
allowed_domains = ['uumdfdfnt.94demo.com'] 。
allowed_urls = ['http://uumdfdfnt.94demo.com/'] 。
# 需要爬取的网站url加到start_urls list里 。
start_urls = ['http://uumdfdfnt.94demo.com/tag/dingziku/index.html'] 。
save_path = '/home/sexy/dingziku' 。
def parse(self, response): 。
# 解析网站,获取图片列表 。
img_list = response.xpath('//div[@class="taglist"]/ul//li//a//img/@data-original').getall() 。
time.sleep(1) 。
# 处理图片, 具体业务操作, 可交给yield items 。
for img_url in img_list: 。
items = SexyItem() 。
items['img_url'] = img_url 。
yield items 。
import os 。
import requests 。
def download_from_url(url): 。
response = requests.get(url, stream=True) 。
if response.status_code == requests.codes.ok: 。
return response.content 。
else: 。
print('%s-%s' % (url, response.status_code)) 。
return None 。
class SexyPipeline(object): 。
def __init__(self): 。
self.save_path = '/tmp' 。
def process_item(self, item, spider): 。
if spider.name == 'sexy': 。
# 取出item里内容 。
img_url = item['img_url'] 。
# 业务处理 。
file_name = img_url.split('/')[-1] 。
content = download_from_url(img_url) 。
if content is not None: 。
with open(os.path.join(self.save_path, file_name), 'wb') as fw: 。
fw.write(content) 。
return item 。
ITEM_PIPELINES = { 。
'sexy.pipelines.SexyPipeline': 300, 。
} 。
5.3 自动下一页 。
有时候我们不仅要爬取请求页面中的内容,还要递归式的爬取里面的超链接url,特别是下一页这种,解析内容和当前页面相同的情况下。一种笨方法是手动加到start_urls里。大家都是聪明人来试试这个.
完美了,完整例子见5.1 。
next_page = response.xpath('//div[@class="page both"]/ul/a[text()="下一页"]/@href').get() 。
if next_page is not None: 。
next_page = response.urljoin(next_page) 。
yield scrapy.Request(next_page, callback=self.parse) 。
5.4 中间件 。
这里举一个添加模拟浏览器请求的方式,防止爬虫被封锁。重写process_request 。
from scrapy.contrib.downloadermiddleware.useragent import UserAgentMiddleware 。
import random 。
agents = ['Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;', 。
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv,2.0.1) Gecko/20100101 Firefox/4.0.1', 。
'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11', 。
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11', 。
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'] 。
class RandomUserAgent(UserAgentMiddleware): 。
def process_request(self, request, spider): 。
ua = random.choice(agents) 。
request.headers.setdefault('User-agent',ua,) 。
统一要在settings.py中开启下载中间件,数值表示优先级 。
DOWNLOADER_MIDDLEWARES = { 。
'sexy.middlewares.customUserAgent.RandomUserAgent': 20, 。
} 。
5.5 可用配置settings.py 。
除了上面提供的pipline配置开启和中间件配置外,下面介绍几个常用的配置 。
所有的配置详见 https://doc.scrapy.org/en/latest/topics/settings.html 。
6. 总结 。
相信从上面的介绍,你已经可以动手写一个你自己的爬虫了。我也完成了做笔记的任务了。scrapy还提供更加详细的细节,可参见https://docs.scrapy.org/en/latest/.
最后总结如下:
原文地址:https://mp.weixin.qq.com/s/cuJlzYFSL-o-n2RN2tqv_A 。
最后此篇关于5分钟快速掌握scrapy爬虫框架的文章就讲到这里了,如果你想了解更多关于5分钟快速掌握scrapy爬虫框架的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在尝试理解 promise ,在本例中是在一个循环中。 我的场景基于将文件上传到 Google 云端硬盘。我的理解是,每个文件都应该上传,然后一旦 promise 得到解决,就上传下一个文件,依此
JDK 1.6 包括通过 JAX-WS API 使用 FastInfoset Web 服务的功能。这些的实现隐藏在 com.sun.xml.internal 的深处,包名旨在让任何明智的 Java 开
我正在学习 React 并思考组件的结构。以下内容让我有些困惑。 我们被告知应该有单一的真相来源。 所有者组件应将 props/状态传递给它的责任(有些人称为“ownee”)组件。 所以,如果我自己的
我刚刚开始使用 Google Guice 作为依赖项注入(inject)框架,并试图将其改造为我最近编写的中小型项目。我了解 Guice 工作原理的基础知识,但对一些方法细节有点模糊。例如: 1) 模
上周我们在上周左右的修补和测试后将 Omniture 的分析代码发布到大量网站上。 在我们几乎所有的网站模板上,它都运行良好。在一些零星的、不可预测的情况下,严重的浏览器崩溃体验可能会让一些用户望而却
我刚刚获得了一个 API,它似乎比我习惯的更上一层楼,因为一切似乎都是使用接口(interface)实现的,我正在努力理解它们。 public partial class Form1 : Form,
我的程序似乎很合我意。但是,当我编译它时,我收到了这条消息: Note: Program.java uses unchecked or unsafe operations. Note: Recompi
最近开始用story board、Xcode等学习Swift。我很难理解 ViewController 代码的原理,因为它似乎遗漏了很多基本要素——大概是为了尝试让事情变得更简单——但它不适合来自其他
我刚收到一些有关使用 wpf、c# 的 MVVM 的设计/实现问题。我只是想掌握 MVVM,如果有人能证实我的想法,我正在徘徊,在我的应用程序中,我需要一名员工、一个部门和一家公司。所以换句话说,我有
我在 gird View 中有一个 gridview 和 2 个链接按钮,编辑和删除,单击编辑按钮 s 时,该行的详细信息应显示在“detailsview”中。我的详细信息 View 在更新面板。 最
function def() { console.log(this.x) } var f = def.bind({ x:777 }) f() // prints 777 bind 创建了一个函
我尝试将谷歌地图(外部加载的脚本)添加到 meteor 应用程序,但没有成功,我注意到有两种问题: 如果我做简单的事情并将主要的 API 脚本添加到我的 ,然后它被呈现为last。 发生这种情况时,
如果我理解正确,Node JS 是非阻塞的......所以它不是等待来自数据库或其他进程的响应,而是转移到其他东西并稍后再检查。 它也是单线程的。 这是否意味着给定的 Node JS 进程可以充分有效
几周前,我开始了 Iphone 应用程序开发的研究,在不同设置中进行了大量的 hello world 应用程序之后,我现在已经准备好开发我的第一个基于 Cocoa 中使用的 MVC 设计模式的应用程序
这个问题和我之前的问题很相似。 大约 4 年前,我在 Visual Studio 2005 中使用过 ASP .Net。恢复最新版本需要多长时间? 最佳答案 这取决于您“使用”它的程度。有经验的开发人
如何让这个程序让用户一次输入 5 位数字,而不是每次都询问单独的数字?我知道我必须使用 string.split() 但我将在哪里放置代码并执行代码。 Heading from random impo
因此,根据我的理解,在 3nf 数据库中,主键值可用于确定表中的每个其他属性。 这是否意味着外键将专门用于创建复合实体?外键如何适合 3nf 数据库? 有哪些“迹象”表明我的数据库已标准化?数据库中的
如何解决以下 f(n)=n!据我所知不适用于主定理的任何情况。T(n) = 16T(n/4) + n! 最佳答案 David Eisenstat 部分正确。情况 3 确实适用,但 T(n) = the
在过去的 2.5 年里,我一直在研究 SAP 技术。由于技术概念太多,我无法找到一个可以了解与它相关的所有内容的单一来源。我没有掌握掌握所有技术概念的信心。 如果您遇到过这样的经历以及如何克服它,请帮
我是一名优秀的程序员,十分优秀!