Python网络爬虫2 ---- scrapy爬虫架构介绍和初试

本文涉及的产品
.cn 域名,1个 12个月
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 原文出处:http://my.oschina.net/dragonblog/blog/173290 上一篇文章的环境搭建是相对于手动操作的过程,而大家可能对这个疑问是什么是scrapy?为什么要用scrapy?下面主要是对这两个问题的简要回答。

原文出处:http://my.oschina.net/dragonblog/blog/173290


上一篇文章的环境搭建是相对于手动操作的过程,而大家可能对这个疑问是什么是scrapy?为什么要用scrapy?下面主要是对这两个问题的简要回答。

请尊重作者的工作,转载请注明出处http://my.oschina.net/dragonblog/blog/173545

相信大家在百度或google上一搜索scrapy都能够找到一大堆的结果,由于我本人对scrapy没有太了解,因此这里我也是引用了网络上的说法对scrapy进行说明,也希望各位能够多指点一下小弟。

========================华丽的分割线========================

Scrapy 是一套基于Twisted的异步处理框架,是纯python实现的爬虫框架,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容或者各种图片。下图显示了Scrapy的大体架构,其中包含了scheduler、item pipeline、downloader、spider以及engine这几个组件模块,而其中的绿色箭头则说明了整套系统的数据处理流程。


下面就来一个个解释每个组件的作用及数据的处理过程。

一、组件说明:

    1、Scrapy Engine(Scrapy引擎)

    Scrapy引擎是用来控制整个系统的数据处理流程,并进行事务处理的触发。更多的详细内容可以看下面的数据处理流程。

    2、Scheduler(调度)

    调度程序从Scrapy引擎接受请求并排序列入队列,并在Scrapy引擎发出请求后返还给他们。

    3、Downloader(下载器)

    下载器的主要职责是抓取网页并将网页内容返还给蜘蛛( Spiders)。

    4、Spiders(蜘蛛)

    蜘蛛是有Scrapy用户自己定义用来解析网页并抓取制定URL返回的内容的类,每个蜘蛛都能处理一个域名或一组域名。换句话说就是用来定义特定网站的抓取和解析规则。

    蜘蛛的整个抓取流程(周期)是这样的:

    (1)首先获取第一个URL的初始请求,当请求返回后调取一个回调函数。第一个请求是通过调用start_requests()方法。该方法默认从start_urls中的Url中生成请求,并执行解析来调用回调函数。

    (2)在回调函数中,你可以解析网页响应并返回项目对象和请求对象或两者的迭代。这些请求也将包含一个回调,然后被Scrapy下载,然后有指定的回调处理。

    (3)在回调函数中,你解析网站的内容,同程使用的是Xpath选择器(但是你也可以使用BeautifuSoup, lxml或其他任何你喜欢的程序),并生成解析的数据项。

    (4)最后,从蜘蛛返回的项目通常会进驻到项目管道。

5、Item Pipeline(项目管道)

    项目管道的主要责任是负责处理有蜘蛛从网页中抽取的项目,他的主要任务是清晰、验证和存储数据。当页面被蜘蛛解析后,将被发送到项目管道,并经过几个特定的次序处理数据。每个项目管道的组件都是有一个简单的方法组成的Python类。他们获取了项目并执行他们的方法,同时他们还需要确定的是是否需要在项目管道中继续执行下一步或是直接丢弃掉不处理。

项目管道通常执行的过程有:

  1. 清洗HTML数据
  2. 验证解析到的数据(检查项目是否包含必要的字段)
  3. 检查是否是重复数据(如果重复就删除)
  4. 将解析到的数据存储到数据库中

6、Downloader middlewares(下载器中间件)

    下载中间件是位于Scrapy引擎和下载器之间的钩子框架,主要是处理Scrapy引擎与下载器之间的请求及响应。它提供了一个自定义的代码的方式来拓展 Scrapy的功能。下载中间器是一个处理请求和响应的钩子框架。他是轻量级的,对Scrapy尽享全局控制的底层的系统。

7、Spider middlewares(蜘蛛中间件)

    蜘蛛中间件是介于Scrapy引擎和蜘蛛之间的钩子框架,主要工作是处理蜘蛛的响应输入和请求输出。它提供一个自定义代码的方式来拓展Scrapy的功能。蛛中间件是一个挂接到Scrapy的蜘蛛处理机制的框架,你可以插入自定义的代码来处理发送给蜘蛛的请求和返回蜘蛛获取的响应内容和项目。

8、Scheduler middlewares(调度中间件)

    调度中间件是介于Scrapy引擎和调度之间的中间件,主要工作是处从Scrapy引擎发送到调度的请求和响应。他提供了一个自定义的代码来拓展Scrapy的功能。

二、数据处理流程

Scrapy的整个数据处理流程由Scrapy引擎进行控制,其主要的运行方式为:

  1. 引擎打开一个域名,时蜘蛛处理这个域名,并让蜘蛛获取第一个爬取的URL。
  2. 引擎从蜘蛛那获取第一个需要爬取的URL,然后作为请求在调度中进行调度。
  3. 引擎从调度那获取接下来进行爬取的页面。
  4. 调度将下一个爬取的URL返回给引擎,引擎将他们通过下载中间件发送到下载器。
  5. 当网页被下载器下载完成以后,响应内容通过下载中间件被发送到引擎。
  6. 引擎收到下载器的响应并将它通过蜘蛛中间件发送到蜘蛛进行处理。
  7. 蜘蛛处理响应并返回爬取到的项目,然后给引擎发送新的请求。
  8. 引擎将抓取到的项目项目管道,并向调度发送请求。
  9. 系统重复第二部后面的操作,直到调度中没有请求,然后断开引擎与域之间的联系。

========================华丽的分割线========================

以上部分是属于网上抄过来的,谁是第一手就无可考究了,对于大家是否能看明白就没有保证了,我本还还算能够明白七成吧。

上面两个分割线中的内容也算得是回答了第一个问题了,那么为什么要用scrapy呢?我有一个习惯,在提出问题的时候都会先再找一个问题,对于这个问题而提出的问题是:我自己写一个不行吗?

刚开始的时候我也是这样想的,于是就自己开始找python怎么抓网页数据之类的了,后来还弄了一个不堪入目的一段代码,用于从一个根网页中找到所有的链接,然后将这些链接都放到一个列表中,然后弄个循环从这个列表中一个个去抓。下面就是我之前第一次接触python时写的代码(不堪入目,不喜勿喷。。。)

001 #encoding=utf-8
002
003 __author__ = 'dragon'
004
005 import urllib2
006 import os
007 import pymongo
008 import time
009 import hashlib
010
011 def myspider(startweb, keyword):
012     list = [startweb]
013     curindex = 0
014     Keyword = keyword
015
016     #网络上MongoHQ
017     #con = pymongo.Connection("paulo.mongohq.com", 10042)
018     #db = con.mytest
019     #db.authenticate("dragon", "dragon")
020     #db.urllist.drop()
021
022     #本地数据库
023     con = pymongo.Connection("localhost"27017)
024     db = con.mytest
025
026     while curindex < len(list):
027         url = list[curindex]
028         print "list count ="len(list), "  curcheck ", curindex
029         print "try to visit ", url
030
031         headers = ('User-Agent''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36')
032
033         try:
034             opener = urllib2.build_opener()
035             opener.addheaders = [headers]
036             openness = opener.open(url, None30)
037             data = openness.read()
038             opener.close()
039         except:
040             print "some error ..."
041             curindex += 1
042             continue
043
044         print "finish get data..."
045
046         os.remove("d:/test.txt")
047         file = open("d:/test.txt""a")
048         print >> file, data
049         file.close()
050
051         myfile      = open("d:/test.txt""r")
052         mystring    = myfile.read()
053         myfile.close()
054
055         #找到标题
056         title       = ""
057         headstart   = mystring.find("<head>")
058         headend     = mystring.find("</head>")
059         if headstart < 0:
060             headstart   = mystring.find("<HEAD>")
061             headend     = mystring.find("</HEAD>")
062
063         if headstart > 0:
064             titlestart  = mystring.find("<title>")
065             titleend    = mystring.find("</title>")
066             if titlestart < 0:
067                 titlestart  = mystring.find("<TITLE>")
068                 titleend    = mystring.find("</TITLE>")
069
070             if titleend > titlestart and titlestart < headend and titleend < headend:
071                 title = mystring[titlestart+len("<title>"):titleend]
072
073         dbdata = {"title":"", "url":"", "time":""}
074
075         try:
076             title = title.decode("utf-8").encode("utf-8")
077         except:
078             try:
079                 title = title.decode("gbk").encode("utf-8")
080             except:
081                 pass
082
083
084         dbdata["title"= title
085         dbdata["url"= url
086         dbdata["time"= time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
087         try:
088             db.urllist.insert(dbdata)
089         except:
090             print "insert error"
091
092         if len(mystring) > 0:
093             while len(mystring) > 0:
094                 start = mystring.find("href=\"")
095                 if start <= 0:
096                     break
097
098                 substring = mystring[start+6:]
099                 end = substring.find("\"")
100                 weblink = substring[:end]
101                 if Keyword != "":
102                     if weblink.find(Keyword) >= 0 and list.count(weblink) <= 0:
103                         list.append(weblink)
104                 elif 0 > weblink.find("video.sina.com.cn") \
105                     and 0 > weblink.find("video.baidu.com") \
106                     and 0 <= weblink.find("http:") \
107                     and 0 >= list.count(weblink):
108
109                     list.append(weblink)
110
111                 mystring = mystring[start+6:]
112
113         curindex += 1
114
115 if __name__ == '__main__':
116     myspider("http://www.hao123.com""hao123")

处理的流程是:

    1. 将一个开始的网页url存放到list中

    2. 不断从list中取出url进行数据获取

    3. 在获取到的网页数据中的链接都存放到list里面

    4. 不断重复2、3步骤

上面这段代码写得怎么样就不值得评论了,但是值得我们思考的是,上面的代码出发点是爬虫,并且还是漫无目的的爬虫,没有了终点,或者大家会想到很多退出循环的方法,但是我们还有很多问题需要考虑:如何提高爬虫的效率?如何最大限度利用网络带宽?如果提高抓取回来数据的处理?最重要一点是:我们都不会想着去做google或百度,而是针对一些特定的需求来实现一个爬虫,那么我们如何简单而又快速的去实现我们的定制功能呢?

上面的几个问题就是我们最终都会遇到的问题,也是scrapy能够很好的处理的问题,它通过几个组件完成不同的部分,将类似下载网页数据的这些通用操作封装起来,减少了我们编写爬虫时的难度,并且各个部件之间通过异步来处理,能够最大限度利用了网络带宽。我们只需要按照它的要求来实现几个模块就可以了。

最后,讲讲使用如何生成一个scrapy工程。

打开cmd,cd到你要创建工程的目录,然后使用以下命令创建工程test:

    scrapy startproject test

如下图所示,我们看到创建了一个test文件夹,里面包含了其他一些文件

根据上图可以对照第一幅图,找到一些组件的对应文件,我们可以在spider下面创建一个py文件(例如:spider.py),然后写上以下代码:

1 from scrapy.spider import BaseSpider
2
3 class test(BaseSpider):
4     name = "test"
5     allowed_domains = ["hao123.com"]
6     start_urls = ["http://www.hao123.com"]
7
8     def parse(self, response):
9         print response.url
在cmd中,cd进入刚才创建的test目录,使用以下命令运行这个爬虫,我们可以最后看到一些debug输出

这篇文章到此为止,写得比较粗糙。可能大家对于spider.py中的一些变量和函数名称,以及该模块什么时候被调用存在疑问,大家可以上网找找资料学习,我将在下一篇文件中说明,并且以获取百度文库中的图书信息作为例子,完成相关的代码并提供源码。


目录
相关文章
|
27天前
|
数据采集 中间件 开发者
Scrapy爬虫框架-自定义中间件
Scrapy爬虫框架-自定义中间件
46 1
|
3月前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。
156 4
|
3月前
|
数据采集 存储 搜索推荐
打造个性化网页爬虫:从零开始的Python教程
【8月更文挑战第31天】在数字信息的海洋中,网页爬虫是一艘能够自动搜集网络数据的神奇船只。本文将引导你启航,用Python语言建造属于你自己的网页爬虫。我们将一起探索如何从无到有,一步步构建一个能够抓取、解析并存储网页数据的基础爬虫。文章不仅分享代码,更带你理解背后的逻辑,让你能在遇到问题时自行找到解决方案。无论你是编程新手还是有一定基础的开发者,这篇文章都会为你打开一扇通往数据世界的新窗。
|
4月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
【7月更文挑战第31天】在网络数据的海洋中,使用Python的`requests`库构建网络爬虫就像探索未知的航船。HTTP协议指导爬虫与服务器交流,收集信息。HTTP请求包括请求行、头和体,响应则含状态行、头和体。`requests`简化了发送各种HTTP请求的过程。
80 4
|
1月前
|
数据采集 存储 数据挖掘
深入探索 Python 爬虫:高级技术与实战应用
本文介绍了Python爬虫的高级技术,涵盖并发处理、反爬虫策略(如验证码识别与模拟登录)及数据存储与处理方法。通过asyncio库实现异步爬虫,提升效率;利用tesseract和requests库应对反爬措施;借助SQLAlchemy和pandas进行数据存储与分析。实战部分展示了如何爬取电商网站的商品信息及新闻网站的文章内容。提醒读者在实际应用中需遵守法律法规。
156 66
|
23天前
|
数据采集 JavaScript 前端开发
JavaScript逆向爬虫——使用Python模拟执行JavaScript
JavaScript逆向爬虫——使用Python模拟执行JavaScript
22 2
|
23天前
|
消息中间件 数据采集 数据库
小说爬虫-03 爬取章节的详细内容并保存 将章节URL推送至RabbitMQ Scrapy消费MQ 对数据进行爬取后写入SQLite
小说爬虫-03 爬取章节的详细内容并保存 将章节URL推送至RabbitMQ Scrapy消费MQ 对数据进行爬取后写入SQLite
16 1
|
23天前
|
消息中间件 数据采集 数据库
小说爬虫-02 爬取小说详细内容和章节列表 推送至RabbitMQ 消费ACK确认 Scrapy爬取 SQLite
小说爬虫-02 爬取小说详细内容和章节列表 推送至RabbitMQ 消费ACK确认 Scrapy爬取 SQLite
16 1
|
28天前
|
安全 数据安全/隐私保护 UED
优化用户体验:前后端分离架构下Python WebSocket实时通信的性能考量
在当今互联网技术的迅猛发展中,前后端分离架构已然成为主流趋势,它不仅提升了开发效率,也优化了用户体验。然而,在这种架构模式下,如何实现高效的实时通信,特别是利用WebSocket协议,成为了提升用户体验的关键。本文将探讨在前后端分离架构中,使用Python进行WebSocket实时通信时的性能考量,以及与传统轮询方式的比较。
55 2
|
2月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
在网络数据的海洋中,网络爬虫遵循HTTP协议,穿梭于互联网各处,收集宝贵信息。本文将从零开始,使用Python的requests库,深入解析HTTP协议,助你构建自己的网络爬虫帝国。首先介绍HTTP协议基础,包括请求与响应结构;然后详细介绍requests库的安装与使用,演示如何发送GET和POST请求并处理响应;最后概述爬虫构建流程及挑战,帮助你逐步掌握核心技术,畅游数据海洋。
64 3

热门文章

最新文章