爬虫进阶:框架功能完善-金年会app官方网
爬虫实现多个解析函数
响应对象的解析方法封装
为response对象封装xpath、正则、json、等方法和属性,以支持对数据的解析和提取
# scrapy_plus/http/response.py
import re
import json
from lxml import etree
class response(object):
'''框架内置response对象'''
def __init__(self, url, status_code, headers, body):
self.url = url # 响应url
self.status_code = status_code # 响应状态码
self.headers = headers # 响应头
self.body = body # 响应体
def xpath(self, rule):
'''提供xpath方法'''
html = etree.html(self.body)
return html.xpath(rule)
@property
def json(self):
'''提供json解析
如果content是json字符串,是才有效
'''
return json.loads(self.body)
def re_findall(self, rule, data=none):
'''封装正则的findall方法'''
if data is none:
data = self.body
return re.findall(rule, data)
实现多个解析函数
由于现在不同的请求对应不同的解析函数,因此需要为请求对象指明它的解析函数,因此为请求对象增加一个属性
# scrapy_plus/http/request.py
class request(object):
'''框架内置请求对象,设置请求信息'''
def __init__(self, url, method='get', headers=none, params=none, data=none, parse='parse'):
self.url = url # 请求地址
self.method = method # 请求方法
self.headers = headers # 请求头
self.params = params # 请求参数
self.data = data # 请求体
self.parse = parse # 指明它的解析函数, 默认是parse方法
self.meta = none
# scrapy_plus/http/response.py
class response:
'''完成对响应对象的封装'''
def __init__(self, url, body, headers, status_code, meta={}):
'''
初始化resposne对象
:param url: 响应的url地址
:param body: 响应体
:param headers: 响应头
:param status_code: 状态码
'''
self.url = url
self.headers = headers
self.status_code = status_code
self.body = body
self.meta = meta
在引擎中需要动态的判断和获取对应的解析函数
# scrapy_plus/core/engine.py
class engine(object):
......
def _execute_request_response_item(self):
'''根据请求、发起请求获取响应、解析响应、处理响应结果'''
......
#request对象经过下载器中间件的process_request进行处理
request = self.downloader_mid.process_request(request)
#4. 调用下载器的get_response方法,获取响应
response = self.downloader.get_response(request)
response.meta = request.meta
#response对象经过下载器中间件的process_response进行处理
response = self.downloader_mid.process_response(response)
#response对象经过下爬虫中间件的process_response进行处理
response = self.spider_mid.process_response(response)
#parse方法
parse = getattr(self.spider,request.parse)
#5. 调用爬虫的parse方法,处理响应
for result in parse(response):
#6.判断结果的类型,如果是request,重新调用调度器的add_request方法
if isinstance(result,request):
#在解析函数得到request对象之后,使用process_request进行处理
result = self.spider_mid.process_request(result)
self.scheduler.add_request(result)
self.total_request_nums = 1
#7如果不是,调用pipeline的process_item方法处理结果
else:
self.pipeline.process_item(result)
self.total_response_nums = 1
......