🚀 隆重推出 ✨ Bose 框架 - 机器人开发者的瑞士军刀 🤖
机器人开发很困难。
像 Cloudflare 这样的机器人检测器已经准备好保护网站免受机器人的攻击。使用 ChromeOptions 配置 Selenium 来指定驱动程序路径、配置文件、用户代理和窗口大小非常繁琐,在 Windows 系统中更是噩梦。通过日志调试机器人崩溃问题非常困难。如何在不牺牲速度和便捷开发体验的情况下解决这些痛点?
来认识一下 Bose。Bose 是开发者社区中第一个专为机器人开发者提供最佳开发体验而设计的机器人开发框架。它由 Selenium 提供支持,提供一系列特性和功能,以简化机器人开发流程。据我们所知,Bose 是业内首个此类机器人开发框架。
入门
克隆入门模板
git clone https://github.com/omkarcloud/bose-starter my-bose-project
然后进入该目录,安装依赖项,并启动项目:
cd my-bose-project
python -m pip install -r requirements.txt
python main.py
第一次运行将需要一些时间,因为它会下载 chrome 驱动程序可执行文件,后续运行将会很快。
核心功能
- 添加强大的方法,使使用 Selenium 变得更加容易。
- 遵循最佳实践以避免 Cloudflare 和 PerimeterX 的机器人检测。
- 保存每个任务运行的 HTML、屏幕截图和运行详细信息,以便于轻松调试。
- 将抓取的数据写入 JSON、CSV 和 Excel 文件的实用组件。
- 自动下载并初始化正确的 Chrome 驱动程序。
- 快速且对开发人员友好。
用法
假设你想开始抓取一个网站的数据。如果你使用的是裸 Selenium,那么你必须像这样处理打开和关闭驱动程序的必要任务:
from selenium import webdriver
driver_path = 'path/to/chromedriver'
driver = webdriver.Chrome(executable_path=driver_path)
driver.get('https://www.example.com')
driver.quit()
但是,使用 Bose 框架,您可以采用声明式和结构化的方法。您只需编写以下代码,Bose 驱动程序将负责创建驱动程序、将其传递给run
Task 的方法以及关闭驱动程序:
from bose import *
class Task(BaseTask):
def run(self, driver):
driver.get('https://www.example.com')
配置
在裸 Selenium 中,如果要配置配置文件、用户代理或窗口大小等选项,则需要编写大量代码,如下所示:
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
driver_path = 'path/to/chromedriver.exe'
options = Options()
profile_path = '1'
options.add_argument(f'--user-data-dir={profile_path}')
user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.37")'
options.add_argument(f'--user-agent={user_agent}')
window_width = 1200
window_height = 720
options.add_argument(f'--window-size={window_width},{window_height}')
driver = webdriver.Chrome(executable_path=driver_path, options=options)
另一方面,Bose Framework 通过将浏览器配置封装在BrowserConfig
Task 的属性中来简化这些复杂性,如下所示:
from bose import BaseTask, BrowserConfig, UserAgent, WindowSize
class Task(BaseTask):
browser_config = BrowserConfig(user_agent=UserAgent.user_agent_106, window_size=WindowSize.window_size_1280_720, profile=1)
异常处理
使用 Selenium 时,异常很常见。在裸 Selenium 中,如果发生异常,驱动程序会自动关闭,只留下日志供您调试。
在 Bose 中,当抓取任务发生异常时,浏览器会保持打开状态,而不是立即关闭。这允许您查看异常发生时的实时浏览器状态,这对调试非常有帮助。
调试
网页抓取经常会出现错误,例如错误的选择器或页面加载失败。使用原始 Selenium 进行调试时,您可能需要仔细检查日志才能发现问题。幸运的是,Bose 会存储每次运行的信息,让您能够轻松调试。
每次运行后,任务中都会创建一个目录,其中包含三个文件,如下所示:
task_info.json
它包含有关任务运行的信息,例如任务运行的持续时间、任务的 IP 详细信息、用户代理、window_size 和用于执行任务的配置文件。
final.png
这是驱动程序关闭之前捕获的屏幕截图。
page.html
这是驱动程序关闭前捕获的 HTML 源代码。如果你的选择器无法选择元素,这非常有用。
error.log
如果您的任务因异常而崩溃,我们还会存储 error.log,其中包含导致任务崩溃的错误信息。这在调试过程中非常有用。
输出数据
执行网页抓取后,我们需要将数据存储为 JSON 或 CSV 格式。通常,此过程需要编写大量命令式代码,如下所示:
import csv
import json
def write_json(data, filename):
with open(filename, 'w') as fp:
json.dump(data, fp, indent=4)
def write_csv(data, filename):
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = data[0].keys() # get the fieldnames from the first dictionary
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader() # write the header row
writer.writerows(data) # write each row of data
data = [
{
"text": "\u201cThe world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.\u201d",
"author": "Albert Einstein"
},
{
"text": "\u201cIt is our choices, Harry, that show what we truly are, far more than our abilities.\u201d",
"author": "J.K. Rowling"
}
]
write_json(data, "data.json")
write_csv(data, "data.csv")
Bose 通过将这些复杂性封装在输出模块中来读取和写入数据,从而简化了这些复杂性。
要使用输出方法,请调用 write
您想要保存的文件类型的方法。
所有数据将保存在 output/
文件夹中:
请参阅以下代码以供参考
from bose import Output
data = [
{
"text": "\u201cThe world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.\u201d",
"author": "Albert Einstein"
},
{
"text": "\u201cIt is our choices, Harry, that show what we truly are, far more than our abilities.\u201d",
"author": "J.K. Rowling"
}
]
Output.write_json(data, "data.json")
Output.write_csv(data, "data.csv")
未检测到的驱动程序
Ultrafunkamsterdam 创建了一个 ChromeDriver ,它对绕过所有主要的机器人检测系统 (如 Distil、Datadome、Cloudflare 等)具有出色的支持。
Bose 认识到绕过机器人检测的重要性,并为Ultrafunkamsterdam 的 Undetected Driver提供内置支持
在 Bose Framework 中使用未检测到的驱动程序非常简单,只需将use_undetected_driver
选项传递给BrowserConfig
,如下所示:
from bose import BaseTask, BrowserConfig
class Task(BaseTask):
browser_config = BrowserConfig(use_undetected_driver=True)
本地存储
就像现代浏览器具有本地存储模块一样,Bose 也在其框架中融入了相同的概念。
您可以从 Bose 导入 LocalStorage 对象以在浏览器运行期间保存数据,这在抓取大量数据时非常有用。
数据存储在项目根目录中的文件中 local_storage.json
。使用方法如下:
from bose import LocalStorage
LocalStorage.set_item("pages", 5)
print(LocalStorage.get_item("pages"))
老板司机
您在 Task 方法中收到的驱动程序run
是 Selenium 的扩展版本,它添加了强大的方法,使 Selenium 的使用更加便捷。Bose 框架添加到 Selenium 驱动程序中的一些常用方法包括:
方法 | 描述 |
---|---|
get_by_current_page_referrer(链接,等待=无) | 模拟一次访问,就像您通过点击链接到达页面一样。这种方法可以创造更自然、更不易察觉的浏览行为。 |
js_click(元素) | 使您可以使用 JavaScript 点击元素,绕过弹出窗口或警报的任何拦截(ElementClickInterceptedException) |
获取cookies和本地存储字典() | 返回包含“cookies”和“local_storage”的字典 |
添加cookies和本地存储字典(self,site_data) | 将 cookies 和本地存储数据添加到当前网站 |
organic_get(链接,等待=无) | 访问谷歌,然后访问“链接”,使其更难被检测到 |
本地存储 | 返回 LocalStorage 模块的实例,以便以易于使用的方式与浏览器的本地存储进行交互 |
保存屏幕截图(文件名=无) | 将当前网页的屏幕截图保存到tasks/目录中的文件中 |
short_random_sleep() 和 long_random_sleep(): | 睡眠一段时间,可以是 2 到 4 秒(短时间),也可以是 6 到 9 秒(长时间) |
get_element_or_* [例如:get_element_or_none、get_element_or_none_by_selector、get_element_by_id、get_element_or_none_by_text_contains,] | 根据不同的条件在页面上查找 Web 元素。如果 Web 元素存在,则返回该元素;如果不存在,则返回 None。 |
is_in_page(目标,等待=无,raise_exception=False) | 检查浏览器是否位于指定页面 |
Bose 是一个优秀的框架,它简化了 Selenium 和网络抓取的枯燥部分。
祝您使用 Bose Framework 顺利完成 Bot 开发!
了解更多
要详细了解 Bose Bot 开发框架,请阅读https://www.omkar.cloud/bose/上的 Bose 文档