怎样用Python 写一个爬虫框架( 四 )

核心类就是上面的代码,具体实现请看ruia/field.py
接下来继续说Item部分,这部分实际上是对ORM那块的实现,用到的知识点是元类,因为我们需要控制类的创建行为:
class ItemMeta(type): """ Metaclass for an item """ def __new__(cls, name, bases, attrs): __fields = dict({(field_name, attrs.pop(field_name)) for field_name, object in list(attrs.items()) if isinstance(object, BaseField)}) attrs = __fields new_class = type.__new__(cls, name, bases, attrs) return new_classclass Item(metaclass=ItemMeta): """ Item class for each item """ def __init__(self): self.ignore_item = False self.results = {}这一层弄明白接下来就很简单了,还记得上一篇文章《谈谈对Python爬虫的理解》里面说的四个类型的目标网页么:
单页面单目标单页面多目标多页面单目标多页面多目标本质来说就是要获取网页的单目标以及多目标(多页面可以放在Spider那块实现),Item类只需要定义两个方法就能实现:
get_item():单目标get_items():多目标,需要定义好target_item具体实现见:ruia/item.py
Spider 在Ruia框架中,为什么要有Spider,有以下原因:
真实世界爬虫是多个页面的(或深度或广度),利用Spider可以对这些进行 有效的管理制定一套爬虫程序的编写标准,可以让开发者容易理解、交流,能迅速产出高质量爬虫程序自由地定制插件接下来说说代码实现,Ruia框架的API写法我有参考Scrapy,各个函数之间的联结也是使用回调,但是你也可以直接使用await,可以直接看代码示例:
from ruia import AttrField, TextField, Item, Spiderclass HackerNewsItem(Item): target_item = TextField(css_select=\u0026#39;tr.athing\u0026#39;) title = TextField(css_select=\u0026#39;a.storylink\u0026#39;) url = AttrField(css_select=\u0026#39;a.storylink\u0026#39;, attr=\u0026#39;href\u0026#39;)class HackerNewsSpider(Spider): start_urls = async def parse(self, response): async for item in HackerNewsItem.get_items(html=response.html): yield itemif __name__ == \u0026#39;__main__\u0026#39;: HackerNewsSpider.start()使用起来还是挺简洁的,输出如下:
INFO Spider Spider started! INFO Spider Worker started: 4380434912 INFO Spider Worker started: 4380435048 INFO Request \u0026lt;GET: https://news.ycombinator.com/news?p=1\u0026gt; INFO Request \u0026lt;GET: https://news.ycombinator.com/news?p=2\u0026gt; INFO Spider Stopping spider: Ruia INFO Spider Total requests: 2 INFO Spider Time usage: 0:00:03.426335 INFO Spider Spider finished!Spider的核心部分在于对请求URL的请求控制,目前采用的是生产消费者模式来处理,具体函数如下:
怎样用Python 写一个爬虫框架

详细代码,见ruia/spider.py
更多 至此,爬虫框架的核心部分已经实现完毕,基础功能同样一个不落地实现了,接下来要做的就是:


推荐阅读