Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。在之前的博文当中,简要介绍了Scrapy相关工具命令的介绍,以及Scrapy爬虫项目的基本结构。现在,我们需要自己编写一个Scrapy爬虫项目,从之前介绍Scrapy项目结构中可以知道,一个简单的爬虫,只需要对spider
、items.py
以及pipelines.py
做一些相关操作即可,因为它们分别代表着爬虫部分相关的代码,爬虫项目的数据容器以及对爬虫数据的相关处理,这三个步骤对于爬虫项目是最为重要的!!!
Items的编写
使用Scrapy中的Item对象可以保存爬取到的数据,相当于存储爬取到的数据的容器。一般来说,互联网网页中的信息比较庞大,基本上都是非结构化信息,这样的非结构化信息不太利于我们对信息的管理,所以此时,我们可以定义自己所关注的结构化信息,然后从庞大的互联网信息体系中提取出我们关注的结构化信息,这样可以更利于我们对数据的管理,提取之后,这些数据信息需要一个存储的地方,此时,可以将提取到的结构化数据存储到Item对象中。
定义结构化数据信息的格式如下:
结构化数据名 = scrapy.Field()
所以,若要对结构化数据网页标题、网页地址等进行定义。我们打开之前创建的爬虫项目myfirstspider
,可以将items.py的代码修改为如下:
import scrapy
class MyfirstspiderItem(scrapy.Item):
title = scrapy.Field()
url = scrapy.Field()
可以看到,要定义一个结构化数据,只需要将Scrapy下的Field类实例化即可。
我们可以通过Python Shell来实际使用以下Items
,更深入地理解Items
。进入Python Shell,将上面的Items
代码写上,如下:
>>> import scrapy
>>> class MyFirstspiderItem(scrapy.Item):
title = scrapy.Field()
url = scrapy.Field()
>>> item = MyFirstspiderItem(title='测试', url='http://www.baidu.com')
>>> print(item)
{'title': '测试', 'url': 'http://www.baidu.com'}
我们实例化了MyFirstspiderItem
类,并初始化了参数,并且将MyFirstspiderItem
的实例化对象打印了出来。可以发现,对应的数据会以字典的形式存储,原数据项会转变为字典中的字段名,原数据项对应的值会转变为字典中相应字段名对应的值。
如果我们要单独取某个字段对应的值,可以通过:对象名['字段名']
的方式实现。比如,想单独输出对象中的title字段对应的值,可以通过如下方式实现:
>>> item['title']
'测试'
切记,不可以使用.
的方式获取字段的值,否则将引发错误,如下:
>>> item.title
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/Users/xxx/PycharmProjects/demo/venv/lib/python3.7/site-packages/scrapy/item.py", line 92, in __getattr__
raise AttributeError(f"Use item[{name!r}] to get field value")
AttributeError: Use item['title'] to get field value
如果你想要获取该对象中所有的字段名,可以通过如下方式:
>>> item.keys()
dict_keys(['title', 'url'])
如果想获取此时对象中的项目视图,可以通过如下方式:
>>> item.items()
ItemsView({'title': '测试', 'url': 'http://www.baidu.com'})
Item的复制:
>>> item.copy()
{'title': '测试', 'url': 'http://www.baidu.com'}
dict与item的转化
>>> dict_item = dict(item)
>>> type(dict_item)
<class 'dict'>
>>> item = MyFirstspiderItem(dict_item)
>>> type(item)
<class '__main__.MyFirstspiderItem'>