+ 简介
参考地址:http://python.jobbole.com/86405/
Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。Scrapy使用了Twisted异步网络库来处理网络通讯。
Scrapy运行流程大概如下:
引擎从调度器中取出一个链接(URL)用于接下来的抓取
引擎把URL封装成一个请求(Request)传给下载器
下载器把资源下载下来,并封装成应答包(Response)
爬虫解析Response
解析出实体(Item),则交给实体管道进行进一步的处理
解析出的是链接(URL),则把URL交给调度器等待抓取
+ python3.6下Scrapy开发环境搭建
Scrapy的安装有多种方式,它支持Python2.7版本及以上或Python3.3版本及以上。
Scrapy依赖的库比较多,至少需要依赖库有Twisted,lxml,pyOpenSSL。而在不同平台环境又各不相同,所以在安装之前最好确保把一些基本库安装好,尤其是Windows环境下的安装。
(1)安装Visual C++ Build Tools
scrapy底层库依赖C语言编译环境,目前Python3.5和Python3.6依赖的编译环境是Visual C++ 2015 Build Tools,需要先安装Visual C++ Build Tools,如果已经装了Visual Studio 2015机器,就不需要重新再安装Visual C++ 2015 Build Tools。(卸载VS2010,安装VS2015)
(2)安装lxml
Anaconda自带。
(3)pywin32需要手动在下载安装文件安装:https://github.com/mhammond/pywin32/releases
pywin32是一个非常强大的Python扩展库,是Python调用Windows系统底层功能的最佳接口,也是爬虫框架scrapy所依赖的重要扩展库之一。
安装pywin32报错:"Python version 3.6-32 required, which was not found in the registry."
我出现这种情况是因为我直接用的Anaconda,所以注册表没有注册,通过以下代码在注册表中进行注册,注意我提示的错误中版本号是3.6-32,所以注释2处加了-32,根据错误提示信息自行修改即可,注册成功之后双击pywin32-223.win32-py3.6.exe即可安装成功(也可以在windows cmd窗口中输入regedit,自己在注册表中手动修改名称)。
import sys
from winreg import *
# tweak as necessary
version = sys.version[:3]
installpath = sys.prefix
regpath = "SOFTWARE\\Python\\Pythoncore\\%s-32\\" % (version) #注释2
installkey = "InstallPath"
pythonkey = "PythonPath"
pythonpath = "%s;%s\\Lib\\;%s\\DLLs\\" % (
installpath, installpath, installpath
)
def RegisterPy():
try:
reg = OpenKey(HKEY_CURRENT_USER, regpath)
except EnvironmentError as e:
try:
reg = CreateKey(HKEY_CURRENT_USER, regpath)
SetValue(reg, installkey, REG_SZ, installpath)
SetValue(reg, pythonkey, REG_SZ, pythonpath)
CloseKey(reg)
except:
print ("*** Unable to register!")
return
print (" Python", version, "is now registered!")
return
if (QueryValue(reg, installkey) == installpath and
QueryValue(reg, pythonkey) == pythonpath):
CloseKey(reg)
print ("=== Python", version, "is already registered!")
return
CloseKey(reg)
print ("*** Unable to register!")
print ("*** You probably have another Python installation!")
if __name__ == "__main__":
RegisterPy()
(4)安装Twisted
网上下载的Twisted‑17.9.0‑cp36‑cp36m‑win32.whl,进入下载文件目录,执行
pip install Twisted‑17.9.0‑cp36‑cp36m‑win32.whl
(5)安装Scrapy
pip install scrapy
bingo!!!
+ scrapy简单使用介绍
核心流程:parse->yield item->pipeline
cmd进入所要创建工程的目录,scrapy startproject xxx,创建scrapy工程,会创建以下几个文件:
scrapy.cfg:项目的配置文件
xxx:项目
xxx/settings.py:配置文件,定义了一些设置,如用户代理,爬取延时等。
xxx/items.py:目标文件。保存爬取到的数据的容器,其使用方法和python字典类似,并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。Item唯一额外添加的属性是:fields。 Field 对象完完全全就是Python字典(dict)。Item Loaders提供了一种便捷的方式填充抓取到的 :Items 。 虽然Items可以使用自带的类字典形式API填充,但是Items Loaders提供了更便捷的API, 可以分析原始数据并对Item进行赋值。
xxx/pipelines.py:管道文件,定义了数据的存储方式(处理要抓取的域),可以是文件,数据库或者其他。当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。
xxx/middlewares.py:爬虫中间件,该文件可定义随机切换ip或者用户代理的函数。
xxx/spiders:存储爬虫代码目录。为了创建一个Spider,您必须继承 scrapy.Spider 类, 且定义以下三个属性:
(1)name: 用于区别Spider。该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。
(2)start_urls: 包含了Spider在启动时进行爬取的url列表。因此,第一个被获取到的页面将是其中之一。后续的URL则从初始的URL获取到的数据中提取。
(3)parse() 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的Request对象。
scrapy startproject xxx后,进入xxx目录,scrapy genspider -t basic spider_name url,可以创建基本的爬虫框架,
Scrapy为Spider的 start_urls 属性中的每个URL创建了 scrapy.Request 对象,并将 parse 方法作为回调函数(callback)赋值给了Request。Request对象经过调度,执行生成 scrapy.http.Response 对象并送回给spider parse() 方法。
scrapy全局命令:startproject、fetch、veiw、shell、settings、runspider、version、bench
scrapy项目命令:genspider、crawl、check、list、edit、parse、deploy
cmd进入项目目录通过scrapy crawl spider_name运行爬虫,spider_name是爬虫代码文件中定义的爬虫名字。如果运行错误,可以在cmd窗口中查看打印信息。在运行 crawl 时添加 -a 可以传递Spider参数。
import scrapy
class ckf_mm(scrapy.Spider):
name = "ckf_pachong"
def start_requests(self):
urls = [
'http://lab.scrapyd.cn/page/1/',
'http://lab.scrapyd.cn/page/2/',
]
for url in urls:
yield scrapy.Request(url=url,callback=self.parse)
def parse(self,response):
page = response.url.split("/")[-2]
filename = "ckf_mm-%s.html" % page
with open(filename,'wb') as f:
f.write(response.body)
self.log('保存文件:%s' % filename)
+ scrapy数据提取
scrapy提取数据有自己的一套机制,它们被称作选择器(seletors),因为他们通过特定的 XPath 或者 CSS 表达式来“选择” HTML文件中的某个部分。Scrapy选择器构建于 lxml 库之上,这意味着它们在速度和解析准确性上非常相似。
scrapy调试工具:scrapy shell 网址,response.css('标签名')调试查看数据
(1)css提取工具实例
import scrapy
class ckf_mm(scrapy.Spider):
name = "ckf_pachong"
start_urls = ['http://lab.scrapyd.cn']
def parse(self,response):
mingyan = response.css('div.quote')
for v in mingyan:
text = v.css('.text::text').extract_first()
author = v.css('.author::text').extract_first()
tags = v.css('.tags .tag::text').extract()
tags = ','.join(tags)
fileName = '%s-语录.txt' % author
with open(fileName,"a+") as f:
f.write(text)
f.write('\n')
f.write('标签:' + tags)
f.write('\n-------------\n')
f.close()
next_page = response.css('li.next a::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page,callback=self.parse)
爬虫传参:getattr(self, 'tag', None)