Ratel基于urllib和selenium实现request方式和模拟浏览器方式。
在模拟浏览器行为上采用两种浏览器:
在两种操作方式上通过cookie传递可实现快速切换,例如:当进行论坛发布时,通常需要登录账号后才能发布,在模拟登录请求时个别参数难以分析,这时可以采用selenium进行模拟浏览器登录,就像人操作浏览器一样输入账号密码点击登录即可登录,然后将登录成功的cookie传递给request方法即可通过request方式进行发布操作。
在浏览器选择上推荐首选phantomjs,当个别站点页面phantomjs无法渲染时选择chrome浏览器,例如:QQ群管理页面只能通过真实的浏览器渲染页面。
在使用chrome浏览器时系统只能是Windows或Ubuntu系统。chrome现已不支持CentOS系统。若还需Java进行辅助操作只能选择Ubuntu系统或尝试使用除阿里云之外的云机器,因为在阿里云的Windows系统中Thread.sleep命令延时异常不精准可能会卡死。
Ratel适用于Python3以上版本
selenium3.7.0(下载地址: Selenium3.7.0,下载后解压进入项目根目录通过命令:python setup.py install安装或通过pip直接安装,安装命令: pip install -U selenium)
进入Ratel-1.0根目录通过命令:python setup.py install安装
包 | 说明 | 模块 | 说明 |
---|---|---|---|
collect | 采集方式 | request_basic | 实现基于urllib的Request方式 |
-- | -- | webdriver_basic | 实现基于selenium的模拟方式 |
common | 通用模块 | dict | 通用字典,当前版本仅保存默认UA |
main | 主入口 | do_task | 任务执行入口 |
task | 任务 | task_basic | 任务 |
# 导入Task基类
from ratel.task.task_basic import Task
class RequestTask(Task):
def __init__(self):
"""
request方式的任务
"""
self.__url = None
self.__result = None
@property
def get_url(self):
return self.__url
def set_url(self, url):
self.__url = url
@property
def get_result(self):
return self.__result
def set_result(self, result):
self.__result = result
class SeleniumTask(Task):
def __init__(self):
"""
selenium方式的任务
"""
self.__url = None
self.__result = None
@property
def get_url(self):
return self.__url
def set_url(self, url):
self.__url = url
@property
def get_result(self):
return self.__result
def set_result(self, result):
self.__result = result
# 导入Dispose基类
from ratel.task.task_basic import Dispose
class RequestDispose(Dispose):
def __init__(self):
self.__result = None
@property
def get_result(self):
return self.__result
def set_result(self, result):
self.__result = result
def __str__(self):
return '<RequestDispose> result: %s' % self.__result
class SeleniumDispose(Dispose):
def __init__(self):
self.__result = None
@property
def get_result(self):
return self.__result
def set_result(self, result):
self.__result = result
def __str__(self):
return '<SeleniumDispose> result: %s' % self.__result
from ratel.task.task_basic import Execute
from task.demo_task import RequestTask, SeleniumTask
from dispose.demo_dispose import RequestDispose, SeleniumDispose
from ratel.collect.request_basic import Url, request_url
from ratel.collect.webdriver_basic import Driver
import time
import threading
class RequestExecute(Execute):
def __init__(self):
Execute.__init__(self)
def get_task(self):
"""
模拟取任务,任务可使用队列
:return:
"""
while True:
# 模拟创建一条任务
task = RequestTask()
task.set_url(Url(url='http://www.baidu.com', method='GET'))
# 将任务放入至队列
self.put_task(task)
time.sleep(10)
def do_task(self):
"""
模拟执行任务
:return:
"""
# 使用线程取任务, 可不使用
threading.Thread(target=self.get_task, name='get_task', daemon=True).start()
# 使用线程上报任务, 可不使用
threading.Thread(target=self.up_task, name='up_task', daemon=True).start()
while True:
# 判断队列是否为空
if not self.task_empty:
try:
# 从队列中取出任务
task = self.poll_task
# 通知队列任务以取出
self.task_done()
# 执行任务
resp = request_url(url=task.get_url)
# 处理任务结果
task.set_result(self.dispose(resp))
self.put_success(task)
except Exception as e:
print(e)
time.sleep(2)
def dispose(self, result):
"""
模拟处理任务
:param result:
:return:
"""
# 将任务的处理结果放入上报队列
request_dispose = RequestDispose()
request_dispose.set_result(result)
return request_dispose
def up_task(self):
"""
模拟上报任务
:return:
"""
while True:
# 判断队列是否为空
if not self.success_empty:
# 取出任务
task = self.poll_success
self.success_done()
# 模拟上报
print(task.get_result)
time.sleep(2)
def end(self):
"""
任务结束的处理,例如释放资源等
:return:
"""
pass
class SeleniumExecute(Execute):
def __init__(self):
Execute.__init__(self)
def get_task(self):
while True:
task = SeleniumTask()
task.set_url("http://www.baidu.com")
self.put_task(task)
time.sleep(10)
def do_task(self):
# 使用线程取任务, 可不使用
threading.Thread(target=self.get_task, name='get_task', daemon=True).start()
# 使用线程上报任务, 可不使用
threading.Thread(target=self.up_task, name='up_task', daemon=True).start()
while True:
if not self.task_empty:
try:
task = self.poll_task
self.task_done()
# 创建chromeDriver
driver_impl = Driver(driver_type='chrome', executable_path='/Users/xw/Documents/Tools/chromedriver')
driver = driver_impl.get_driver
# 打开浏览器并跳转到指定URL
driver.get(task.get_url)
# 等待页面加载
"""
等待有3种方式
1).time.sleep(),最简单的方式但过于死板,不管页面是否加载完毕都要等待
2).driver.implicitly_wait(),较sleep稍好,但仍有局限性当超过等待时间页面未加载完毕会抛出异常
3).selenium.webdriver.support.wait模块中的WebDriverWait,可根据条件灵活的设置等待时间.
调用该类的until或until_not方法让程序每隔n秒去判断一下条件,看是否满足,如不满足,继续等待直至超时.
超时会抛出TimeoutException异常
"""
time.sleep(5)
result = driver.page_source
driver.close()
task.set_result(self.dispose(result))
self.put_success(task)
except Exception as e:
print(e)
time.sleep(2)
def dispose(self, result):
selenium = SeleniumDispose()
selenium.set_result(result)
return selenium
def up_task(self):
"""
模拟上报任务
:return:
"""
while True:
# 判断队列是否为空
if not self.success_empty:
# 取出任务
task = self.poll_success
self.success_done()
# 模拟上报
print(task.get_result)
time.sleep(2)
def end(self):
pass
# 导入do_task模块
import ratel.main.do_task as do_task
if __name__ == '__main__':
do_task.do_pool()
<!-- 可在任意目录下创建该文件 -->
<config>
<options>
<pool_size>10</pool_size>
</options>
<tasks>
<task>
<task_class>RequestExecute</task_class>
<task_package>execute.demo_execute</task_package>
</task>
</tasks>
</config>
字段 | 说明 |
---|---|
config | 配置 |
options | 系统属性设置 |
pool_size | 进程池大小 |
tasks | 任务集合 |
task | 任务 |
task_class | 执行类 |
task_package | 执行类所在包 |
使用方法同request方式,只需将*config.xml中task_class改为SeleniumExecute即可
方法 | 参数 | 说明 |
---|---|---|
get_task | 无 | 获取任务.任务可使用队列存放.推荐使用多线程调用该方法 |
do_task | 无 | 执行任务.可在该方法内通过线程调用get_task和up_task实现异步获取上报任务 |
up_task | 无 | 上报任务.任务可使用队列存放,推荐使用多线程调用该方法 |
dispose | result | 处理任务结果 |
end | 无 | 任务结束后的处理,例如释放资源,持久化数据等 |
注: 推荐进程池大小大于config.xml中task的数量.
当进程池大小小于总任务数量时多于的任务将延迟执行,直至进程池中有空闲时方能执行
header_default默认请求头,提供Chrome,Firefox,IE的请求头
字段 | 默认值 | 说明 |
---|---|---|
url | 无 | 请求地址,必传.地址中必须包含http://或https:// |
method | GET | 请求方式,支持GET和POST |
header | Chrome_UA | 请求头 |
data | 无 | 请求参数,dict类型,此参数仅对POST方式有效 |
cookie | 无 | CookieJar对象 |
proxy | 无 | 代理ip |
retry_num | 3 | 异常重试次数 |
time_out | 30 | 超时时间,单位秒 |
字段 | 默认值 | 说明 |
---|---|---|
response_code | 无 | 响应码 |
response_content | 无 | 响应内容 |
cookie | 无 | 响应cookie |
request_url | 无 | 请求url |
cookie | 无 | CookieJar对象 |
Driver类,创建webdriver
字段 | 默认值 | 说明 |
---|---|---|
driver_type | 无 | webdriver类型,仅支持chrome和phantomjs,必传 |
executable_path | 无 | 驱动路径 |
headers | 无 | 请求头,chrome仅支持设置UA |
cookies | 无 | cookie,dict类型 |
proxy | 无 | 代理ip |
loadimgs | True | 加载图片,推荐phantomjs禁止加载图片以加快请求速度 |
注:如需使用Firefox, IE 或其他浏览器请参考相关文档,如需在两种方式之间互传cookie需要注意转为对应的类型
Sign in to post a comment
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
Activity
Community
Health
Trend
Influence
:Code submit frequency
:React/respond to issue & PR etc.
:Well-balanced team members and collaboration
:Recent popularity of project
:Star counts, download counts etc.
Repository Comments ( 3 )