scrapy学习笔记0827

1.总之先启动

先安装scrapy,

 pip install scrapy

创建scrapy项目, 生成的项目结构应该如图所示, 

scrapy startproject example

 选择需要爬取的页面并分析,这里选定的页面是All products | Books to Scrape - Sandbox一个供给爬虫学者练手的网站,我们需要爬取上面的书籍信息,解析我们需要的内容在那一段html标签里可以使用浏览器自带的开发者工具进行查看。

找到我们想要的数据在哪里之后,我们就可以开始编写爬虫代码了,

在exmaple/spiders目录下创建新爬虫文件文件book_spider.py,然后在这里面开始实现代码

# -*- coding: utf-8 -*
import scrapy


class BooksSpider(scrapy.Spider):
    # 每一个爬虫的唯一标识
    name = "books"

    # 定义爬虫爬取的起始点,起始点可以是多个,这里只有一个
    start_urls = ["http://books.toscrape.com/"]

    def parse(self, response):
        # 提取数据
        for book in response.css("article.product_pod"):
            name = book.xpath("./h3/a/@title").extract_first()
            price = book.css("p.price_color::text").extract_first()
            yield {
                "name": name,
                "price": price,
            }
            # 提取链接
            next_url = response.css("ul.pager li.next a::attr(href)").extra
            if next_url:
                next_url = response.urljoin(next_url)
                yield scrapy.Request(next_url, callback=self.parse)

每个我们自己定义的爬虫都需要三个因素,name:唯一标识,start_urls:起始爬取url,parse:解析方法。

 运行爬虫,

 scrapy crawl books -o books.csv

圆满完成。

2.为什么可以这样?

scrapy的架构如下,

数据管道:负责处理爬取到的数据

调度器:负责对提交的下载请求进行调度

中间件:处理request和response

下载器:下载页面

scrapy的工作过程如下,

当SPIDER要爬取某URL地址的页面时,需使用该URL构造一个 Request对象,提交给ENGINE。 Request对象随后进入SCHEDULER按某种算法进行排队,之后的 某个时刻SCHEDULER将其出队,送往DOWNLOADER。

DOWNLOADER根据Request对象中的URL地址发送一次HTTP请求到网站服务器,之后用服务器返回的HTTP响应构造出一个 Response对象,其中包含页面的HTML文本。

Response对象最终会被递送给SPIDER的页面解析函数(构造 Request对象时指定)进行处理,页面解析函数从页面中提取 数据,封装成Item后提交给ENGINE,Item之后被送往ITEM PIPELINES进行处理,最终可能由EXPORTER以某种数据格式写入文件(csv,json);另一方面,页 面解析函数还从页面中提取链接(URL),构造出新的Request 对象提交给ENGINE。

3.Request和Response对象

Request对象用来描述一个HTTP请求,

Request(url, callback, method='GET', headers, body, cookies, meta,
 encoding='utf-8', priority=0, dont_filter=False, errback=None)

url:请求页面的url地址,bytes或str类型, 如'http://www.python.org/doc'。

callback:页面解析函数, Callable类型,Request对象请求的页面下载完成后,由该参数指定的页面解析函数被调用。如果未传递该参数,默认调用Spider的parse方法.

method:HTTP请求的方法,默认为'GET'。

headers:HTTP请求的头部字典,dict类型,例如{'Accept': 'text/html', 'User-Agent':Mozilla/5.0'}。如果其中某项的值为None,就表示不发送该项HTTP头部,例如{'Cookie': None},禁止发送Cookie。

body:HTTP请求的正文,bytes或str类型。

cookies:Cookie信息字典,dict类型,例如{'currency': 'country': 'UY'}。

meta:'USD', Request的元数据字典,dict类型,用于给框架中其他组件传递信息,比如中间件Item Pipeline。其他组件可以使用 Request对象的meta属性访问该元数据字典 (request.meta),也用于给响应处理函数传递信息,详见 Response的meta属性。

encoding:url和body参数的编码默认为'utf-8'。如果传入的url或body 参数是str类型,就使用该参数进行编码。

priority:请求的优先级默认值为0,优先级高的请求优先下载。

dont_filter:默认情况下(dont_filter=False),对同一个url地址多次提 交下载请求,后面的请求会被去重过滤器过滤(避免重复下 载)。如果将该参数置为True,可以使请求避免被过滤,强制 下载。例如,在多次爬取一个内容随时间而变化的页面时(每 次使用相同的url),可以将该参数置为True。

errback:请求出现异常或者出现HTTP错误时(如404页面不存在)的回调函数

Response对象用来描述一个HTTP响应,根据响应内容可以有TextResponse,HtmlResponse,XmlResponse,三种类型。

属性与方法有很多,最常用的有css,xpath,urljoin。

4.提取数据的方式

Selector提取有两种方式,css或xpath,都是返回一个SelectorList对象,可以使用正常的for进行遍历。

但首先需要先构建selector对象,1.使用原生的html格式,2.使用response 对象

from scrapy.selector import Selector
 text = '''
 <html>
  <body>
       <h1>Hello World</h1>
      <h1>Hello Scrapy</h1>
    <b>Hello python</b>
       <ul>
           <li>C++</li>
          <li>Java</li>
          <li>Python</li>
        </ul>
   </body>
 </html>
 '''

selector = Selector(text=text)
 response = HtmlResponse(url='http://www.example.com', body=body)
selector = Selector(response=response)

选中元素,

 selector_list = selector.xpath('//h1')
 selector_list[0].extract()
 selector_list.extract_first()
 selector_list[0].re()
 selector_list.re_first()

在我们的实际使用过程中几乎不需要自己定义selector对象,Response对象内部会以自身为参数自动创建Selector对象,并将该Selector对象缓存,以便下次使用。调用更加简洁。 

 response.xpath('.//h1/text()').extract()
 response.css('li::text').extract()

 5.使用自定义数据类处理数据

我们自定义的数据类主要放在item.py文件中,一个文件可以定义多个数据类。

 Item基类:自定义数据类(如BookItem)的基类。

Field类:用来描述自定义数据类包含哪些字段(如name、price等)。

自定义一个数据类,只需继承Item,并创建一系列Field对象的类 属性(类似于在Django中自定义Model)即可。如下,你甚至还可以在自己自定义的代码上进行扩展。

 from scrapy import Item, Field
 class BookItem(Item):
       name = Field()
       price = Field()
class ForeignBookItem(BookItem):
       translator = Field()

在Field中,你便可以对数据进行一些处理,

 authors = Field(serializer=lambda x: '|'.join(x))

 其中,元数据的键serializer是CsvItemExporter规定好的,它会 用该键获取元数据,即一个串行化函数对象,并使用这个串行化函数将 authors字段串行化成一个字符串。

 

 

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值