Scrapy框架 概念笔记1

来源:互联网 发布:有向图的关联矩阵 编辑:程序博客网 时间:2024/06/04 00:23

0.插图一张


任务:利用Scrapy完成网页内容的读取同事筛选出有用(中文+单词+数字)的内容

1.安装配件:
    1.lxml:    lxml是Python语言里和XML以及HTML工作的功能最丰富和最容易使用的库。lxml是为libxml2和libxslt库的一个Python化的绑定。它与众不同的地方是它兼顾了这些库的速度和功能完整性,以及纯Python API的简洁性,大部分与熟知的ElementTree API兼容但比之更优越。
    2.zope.interface:  python支持多继承,但是不支持接口,zope.inteface是其三方的接口实现库,大量用在twisted中
    3.Twisted: 是用Python实现的基于事件驱动的网络引擎框架。
    4.OpenSSL(官网上也只有32位的安装包): SSL是Secure Sockets Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。

2.在当前(shift+rmouse)目录下新建项目:
    scrapy startproject project_name
    1.目录结构如下:
            tutorial/  
                scrapy.cfg  配置文件
                tutorial/  
                    __init__.py  
                    items.py  资源项目
                    pipelines.py  资源目标
                    settings.py  设置资源
                    spiders/  
                        __init__.py  
                        ...  爬虫

    scrapy.cfg:项目的配置文件  (暂时没用到)
    tutorial/:项目的Python模块,将会从这里引用代码
    tutorial/items.py:项目的items文件    (需要导入item包的Item,Field属性,初始化全局的item字典)
    tutorial/pipelines.py:项目的pipelines文件    (设置线程的存储操作等)
    tutorial/settings.py:项目的设置文件    (用于设置COOKIES_ENABLED = False  ITEM_PIPELINES = ['项目名.pipelines.PipelineName']以及优先级)
    tutorial/spiders/:存储爬虫的目录   (爬虫目录,需要导入项目.items中自定义的item类,给item设置有意义的值)

3.明确目标(Item)

在Scrapy中,items是用来加载抓取内容的容器,有点像Python中的Dic,也就是字典,但是提供了一些额外的保护减少错误。
自定义的item可以用scrapy.item.Item类来创建,并且用scrapy.item.Field对象来定义属性(可以理解成类似于ORM的映射关系)。
接下来,我们开始来构建item模型(model)。

首先,我们想要的内容有:
    url = Field()    content(title+keywords+descriptions) = Field()



修改tutorial目录下的items.py文件,自定义所需要的item类。
from scrapy.item import Item,Fieldclass Week1Item(Item):    url = Field()    content = Field()

4.制作爬虫(Spider)

制作爬虫,总体分两步:先爬再取。

也就是说,首先你要获取整个网页的所有内容,然后再取出其中对你有用的部分。

3.1爬

Spider是用户自己编写的类,用来从一个域(或域组)中抓取信息。

他们定义了用于下载的URL列表、跟踪链接的方案、解析网页内容的方式,以此来提取items。

要建立一个Spider,你必须用scrapy.spider.BaseSpider创建一个子类,并确定三个强制的属性:

    name:爬虫的识别名称,必须是唯一的,在不同的爬虫中你必须定义不同的名字。
    start_urls:爬取的URL列表。爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些urls开始。其他子URL将会从这些起始URL中继承性生成。
    parse():解析的方法,调用的时候传入从每一个URL传回的Response对象作为唯一参数,负责解析并匹配抓取的数据(解析为item),跟踪更多的URL。

下面我们来写第一只爬虫,命名为spider1.py,保存在tutorial\spiders目录下。
import scrapyimport refrom week1.items import Week1Itemclass Spider1(scrapy.spiders.Spider):    name = "spider1"    start_urls = []    #从文本(每行一个url)中读取URLs    f = open("H:/spider/week1/week1/urls.txt","r")             for line in f:        start_urls.append(line)    f.close()    def parse(self , response):    #parse使item有实际的意义        item = Week1Item()        #获得本次项目的item        url = response.url + '\t'        # headers = response.headers    headers属性返回response的header字典        # headertext = ''        # for key in headers.keys():        #   headertext += key+': ['+headers[key]+'] '        sel = response.xpath('/html/head')        title = sel.xpath('title/text()').extract()        Keywords = sel.xpath('meta[@name="Keywords"]/@content').extract()        description = sel.xpath('meta[@name="description"]/@content').extract()        content = ''        p_arv = re.compile(u'[^a-zA-Z0-9\u4e00-\u9fa5]+')        if title!=[]:            content+=re.sub(p_arv,' ',title[0])        if Keywords!=[]:            content+=re.sub(p_arv,' ',Keywords[0])        if description!=[]:            content+=re.sub(p_arv,' ',description[0])        content+='\r\n'        item['url'] = url        item['content'] = content        #给item实际的值        yield item        #将字典和每个爬虫类的parse()的函数名函数绑定


3.2提取Item

Selectors选择器简介

从网页中提取数据有很多方法。Scrapy使用了一种基于 XPath 和 CSS 表达式机制: Scrapy Selectors 。 关于selector和其他提取机制的信息请参考 Selector文档 。

这里给出XPath表达式的例子及对应的含义:
    
   
    sel = response.xpath('/html/head')    #在(开始为整个文本)当前标签下逐层的到位:/标签名到这个标签    title = sel.xpath('title/text()').extract()    #标签名选择当前位置下的子标签,text()方法获取标签内的文本,extract()返回一个unicode字符串,该字符串为XPath选择器返回的数据    Keywords = sel.xpath('meta[@name="Keywords"]/@content').extract()    #@属性名=“ ”到达标签的属性


为了配合XPath,Scrapy除了提供了 Selector 之外,还提供了方法来避免每次从response中提取数据时生成selector的麻烦。
    xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 。
    css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表.
    extract(): 序列化该节点为unicode字符串并返回list。
    re(): 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。


使用内置的 Scrapy shell 尝试Selector选择器。Scrapy Shell需要您预装好IPython(一个扩展的Python终端)。
您需要进入项目的根目录,执行下列命令来启动shell:
scrapy shell "url"

在此后尝试用xpath()等获得系列网站风格的数据
当shell载入后,您将得到一个包含response数据的本地 response 变量。输入 response.body 将输出response的包体, 输出 response.headers 可以看到response的包头。

更为重要的是,当输入 response.selector 时, 您将获取到一个可以用于查询返回数据的selector(选择器), 以及映射到 response.selector.xpath() 、 response.selector.css() 的 快捷方法(shortcut): response.xpath() 和 response.css() 。
同时,shell根据response提前初始化了变量 sel 。该selector根据response的类型自动选择最合适的分析规则(XML vs HTML)。

实例:
In [1]: sel.xpath('//title')Out[1]: [<Selector xpath='//title' data=u'<title>Open Directory - Computers: Progr'>]In [2]: sel.xpath('//title').extract()Out[2]: [u'<title>Open Directory - Computers: Programming: Languages: Python: Books</title>']In [3]: sel.xpath('//title/text()')Out[3]: [<Selector xpath='//title/text()' data=u'Open Directory - Computers: Programming:'>]In [4]: sel.xpath('//title/text()').extract()Out[4]: [u'Open Directory - Computers: Programming: Languages: Python: Books']In [5]: sel.xpath('//title/text()').re('(\w+):')Out[5]: [u'Computers', u'Programming', u'Languages', u'Python']



之前提到过,每个 .xpath() 调用返回selector组成的list,因此我们可以拼接更多的 .xpath() 来进一步获取某个节点。我们将在下边使用这样的特性:
for sel in response.xpath('//ul/li'):    title = sel.xpath('a/text()').extract()    link = sel.xpath('a/@href').extract()    desc = sel.xpath('text()').extract()    print title, link, desc



3.3使用item
Item 对象是自定义的python字典。 您可以使用标准的字典语法来获取到其每个字段的值。(字段即是我们之前用Field赋值的属性):
一般来说,Spider将会将爬取到的数据以 Item 对象返回。所以为了将爬取的数据返回,我们最终的代码将是:

简单地讲,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。

4.自定义pipelines
pipe是用于定义基于使用item的爬虫后续操作
class Week1Pipeline(object):    def __init__(self):        self.file = open('C://Users//lenovo//Desktop//week1.txt','wb')    def process_item(self, item, spider):        line = item['url']+item['content']        self.file.write(line.encode('utf-8'))        self.file.close()        return item



5.完善settings

BOT_NAME = 'week1'SPIDER_MODULES = ['week1.spiders']NEWSPIDER_MODULE = 'week1.spiders'COOKIES_ENABLED = False  不生成cookieITEM_PIPELINES = ['week1.pipelines.Week1Pipeline':优先级]


0 0
原创粉丝点击