Scrapling 自带的 TextHandler 与 AttributesHandler 自定义类型如何在自己的项目中使用
【免费下载链接】Scrapling🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!项目地址: https://gitcode.com/GitHub_Trending/sc/Scrapling
假设你的项目里已经用 Scrapling 解析页面,或者你单纯想要两个东西:一个比标准str多带re()、json()、clean()等方法的字符串类型,以及一个只读、带search_values()按值检索的映射类型。Scrapling 把这两个实现放在了核心包里,官方文档明确建议:把它们导入到你自己的代码中复用,比复制它们的源码更好。前提是 Python 3.10 或更高,并按基础方式安装:
pip install scrapling基础安装包含解析引擎及其依赖,这两个类型位于scrapling.core中,属于基础包的一部分,不需要安装fetchers等可选依赖。
导入方式
官方文档给出的导入路径是:
from scrapling.core.custom_types import TextHandler, AttributesHandler另外,包顶层也直接导出了这两个类(惰性导入定义在 scrapling/init.py 中),所以文档解析章节里用的这种写法同样有效:
from scrapling import TextHandler三个类都可单独导入:TextHandler、TextHandlers(List的版本)、AttributesHandler,完整签名参考 Custom Types API Reference。
在普通代码中使用 TextHandler
TextHandler是 Pythonstr的子类,所有标准字符串操作都可用,同时额外提供若干方法。官方文档中给出的最小用法(来自 Using Scrapling's custom types):
from scrapling.core.custom_types import TextHandler somestring = TextHandler('{}') somestring.json()如果你需要在代码里判断类型,文档建议使用 Python 内置的issubclass函数,而不是直接比较type。
在 Scrapling 解析结果中,re/re_first的行为与直接构造的TextHandler一致,Parsing main classes 里给出了可独立运行的示例:
from scrapling import TextHandler test_string = TextHandler('hi there') # 注意两个空格 test_string.re('hi there') # 无匹配 test_string.re('hi there', clean_match=True) # ['hi there'] test_string2 = TextHandler('Oh, Hi Mark') test_string2.re_first('oh, hi Mark') # 无匹配 test_string2.re_first('oh, hi Mark', case_sensitive=False) # 'Oh, Hi Mark' # 参数可以混用 test_string.re('hi there', clean_match=True, case_sensitive=False) # ['hi There']re的可选参数含义(与解析器中同名方法一致):replace_entities默认开启,会把 HTML 实体替换为对应字符;clean_match默认关闭,开启后匹配前忽略空白与连续空格;case_sensitive默认开启,关闭后正则忽略大小写;check_match=True时只做布尔判断,返回是否匹配。
除正则外还有几个可直接复用的方法:
TextHandler('\n wonderful idea, \reh?').clean() # 'wonderful idea, eh?' TextHandler('acb').sort() # 'abc' TextHandler('acb').sort(reverse=True) # 'cba'clean()接受remove_entities参数,传入后同时把 HTML 实体替换为对应字符。.json()方法在内容可以序列化为 JSON 时返回 JSON 对象,否则抛出错误;文档示例(解析<script>内的 JSON 文本):
>>> page.css('#page-data::text').get().json() {'lastUpdated': '2024-09-22T10:30:00Z', 'totalProducts': 3}另外,所有会返回字符串的操作(切片、split、replace、strip等)返回的仍然是TextHandler,所以方法可以链式调用。
在普通代码中使用 AttributesHandler
AttributesHandler是collections.abc.Mapping的子类,官方用它替代标准dict来存储元素属性。构造方式支持字典参数或关键字参数两种(来自官方文档):
from scrapling.core.custom_types import AttributesHandler somedict_1 = AttributesHandler({'a': 1}) somedict_2 = AttributesHandler(a=1)它的核心特征是只读:
- 传入的字符串值会被自动包装成
TextHandler,因此可以attrs['a'].clean()这样继续调用字符串扩展方法; - 标准
dict的读取操作(get、__getitem__、in、迭代、len等)全部可用,任何试图修改数据的操作不可用; - 内部数据通过
_data属性访问,其类型是types.MappingProxyType,同样是只读的,官方注明它比直接暴露Mapping快一点。
它比字典多出的两个能力:
# 1. search_values:按值查找,返回匹配项生成器 for i in attrs.search_values('product'): # 精确匹配 print(i) for i in attrs.search_values('page', partial=True): # 部分匹配 print(i)文档给出的真实页面示例中,page.find('script').attrib.search_values('page-data')输出{'id': 'page-data'}。注意它是生成器,直接放进布尔判断永远为真,需要时先list(...)。
# 2. json_string 属性:属性可 JSON 序列化时返回 JSON 字节串,否则抛错 >>> page.find('script').attrib.json_string b'{"id":"page-data","type":"application/json"}'如果需要修改数据,官方给出的唯一路径是先转换成标准字典:
mutable = dict(attrs) # 之后在 mutable 上修改验证你的用法是否正确
跑完上面的示例后,可以用文档展示过的方式确认类型与行为:
from scrapling.core.custom_types import TextHandler, AttributesHandler t = TextHandler('acb') issubclass(type(t), str) # TextHandler 是 str 的子类 t.sort() # 'abc',返回值仍是 TextHandler,可继续链式调用 a = AttributesHandler({'id': 'page-data'}) type(a).__name__ # 'AttributesHandler',文档中的验证方式 a['id'] # 'page-data' 'a.get' in dir(a) # 具备 dict 的 get 方法 dict(a) # 需要修改时,先转成 dict判定标准:字符串方法链不中断、json()对可解析的 JSON 文本返回对象而非字符串、AttributesHandler的读取操作与字典一致且_data不可写,就说明类型在项目中已按预期工作。仓库中的 tests/parser/test_attributes_handler.py 展示了更完整的属性访问断言,实现细节见 scrapling/core/custom_types.py。
限制
AttributesHandler是只读的,任何写操作都必须先dict()转换,没有原地修改接口。json()与json_string只在内容可 JSON 序列化时工作,否则抛错,而不是返回默认值。- 文档承诺会持续给
TextHandler等新方法,具体方法集以当前版本的 API Reference 为准。
【免费下载链接】Scrapling🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!项目地址: https://gitcode.com/GitHub_Trending/sc/Scrapling
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考