简讯 发表于 2020-2-23 13:44

【Python 爬虫教程】Scrapy 学习笔记(四)

学习 scrapy 中 spider 和 item pipeline 的用法,主要介绍一些方法的使用。[🍇点击此处查看原文。](https://lijianxun.top/114.html)
# spider
## name
每个spider都有自己的名字,这个名字必须唯一,这样我们才能指定运行我们的spider。命名没什么要求,不过尽力要直接体现spider,比如爬取taobao.com,那我们就取名taobao。
## start_urls
爬虫起始列表。这里保存的都是待爬取的URL。
## allowed_domains
用来定义允许爬虫爬取的取名。例如在爬取淘宝过程中爬取到其他域名非taobao.com,那么就跳过。这个选项是可选的。
## custom_settings
先声明这个为字典格式。spider中有一些特殊的配置信息可以使用这个属性,设置以后在运行spider会直接使用custom_settings配置的信息,跳过检查配置文件。
## from_crawler()
我们利用这个方法获取爬虫的配置信息,例如在上一节讲到的:
```python
@classmethod
def from_crawler(cls, crawler):
    return cls(
      mongo_uri=crawler.settings.get('MONGO_URI'),
      mongo_db=crawler.settings.get('MONGO_DB')
      )
```
这个在获取配置信息的时候经常用到。
## start_requests()
这个方法必须返回一个可迭代对象。该对象包含了spider用于爬取的第一个Request。我们可以在参数中定义URL,method,callback等信息。
## make_requests_from_url(url)
该方法接受一个URL并返回用于爬取的Request对象。该方法在初始化request时被start_requests()调用,也被用于转化url为request。
## logger
用来输出日志,例如输出访问网页的状态码: `logger.info(response.status)` 在输出日志中会体现URL的状态码。
## parse
默认回调函数,如果我们在使用过程中没有特殊规定,都是使用这个方法来解析网页。
## closed
当spider关闭时,该函数被调用。例如我们在结束爬虫时要断开与数据库的链接,我们就可以使用这个方法。也可以在运行结束后提示我们已经运行完成。
这些就是spider中常用的方法和属性,读者们可以按需使用,详细内容可以阅读官方文档——(https://doc.scrapy.org/en/latest/topics/spiders.html)。
# Item Pipline
Item Pipline 有很多用处,官方文档举了一些常用的例子。
* cleansing HTML data
* validating scraped data (checking that the items contain certain fields)
* checking for duplicates (and dropping them)
* storing the scraped item in a database
有了这个组件在实际过程中对数据的处理还是很方便的。接下来我们学习编写自己的item pipeline。
## process_item(self, item, spider)
每个 item pipeline 组件都需要调用该方法,这个方法必须返回一个 Item (或任何继承类)对象, 或是抛出 DropItem 异常,被丢弃的 item 将不会被之后的 pipeline 组件所处理。
## open_spider(self, spider)
当 spider 被开启时,这个方法被调用。
## close_spider(spider)
当 spider 被关闭时,这个方法被调用
## from_crawler(cls, crawler)
这个类方法,主要用来获取scrapy项目中的配置信息。
# Item pipeline 例子
举了两个常用的例子,一般来说够用了,官方文档还有其他例子。
## 爬虫获取到item进行操作。
首先判断item的price属性是否存在,如果存在就进行下一步操作,如果不存在就抛出异常。

```python
from scrapy.exceptions import DropItem


class PricePipeline(object):
    vat_factor = 1.15
               
    def process_item(self, item, spider):
      if item['price']:
            if item['price_excludes_vat']:
                item['price'] = item['price'] * self.vat_factor
            return item
      else:
            raise DropItem("Missing price in %s" % item)
```

## 去重
这个例子是一个可以去重的过滤器,丢弃那些已经被处理过的item。我们的item有唯一id,但是返回内容中有许多相同id:
```python
from scrapy.exceptions import DropItem


class DuplicatesPipeline(object):
    def __init__(self):
      self.ids_seen = set()

    def process_item(self, item, spider):
      if item['id'] in self.ids_seen:
            raise DropItem("Duplicate item found: %s" % item)
      else:
            self.ids_seen.add(item['id'])
            return item
```
先定义一个集合,如果id已经存在就删除,如果不存在就添加到集合中。
## 保存到mongo数据库
```python
import pymongo


class MongoPipeline(object):
    collection_name = 'scrapy_items'

    def __init__(self, mongo_uri, mongo_db):
      self.mongo_uri = mongo_uri
      self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls, crawler):
      return cls(
            mongo_uri=crawler.settings.get('MONGO_URI'),
            mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
      )

    def open_spider(self, spider):
      self.client = pymongo.MongoClient(self.mongo_uri)
      self.db = self.client

    def close_spider(self, spider):
      self.client.close()

    def process_item(self, item, spider):
      self.db.insert_one(dict(item))
      return item
```
这段代码利用`from_crawler`方法获取settings中的配置信息,在spider开启时连接到数据库,在spider关闭时间断开与数据库的连接,在执行pipline过程中将item保存到数据库中。
# 配置 item pipline
在settings中找到`ITEM_PIPELINES`属性,写入类的名称和优先级。

```python
ITEM_PIPELINES = {
    'myproject.pipelines.PricePipeline': 300,
    'myproject.pipelines.MongoPipeline': 400,
}
```
数值越小优先级越高,要注意数值的范围是**0~1000**。

凌御逆 发表于 2020-2-23 16:25

感谢楼主分享学习笔记
页: [1]
查看完整版本: 【Python 爬虫教程】Scrapy 学习笔记(四)