python-3.x - 面向对象的方法是否适合我的任务?如果是这样,关于如何实施它的粗略想法?
问题描述
目前正在尝试为我的工作开发一些可以被其他人使用的东西。我知道面向对象的方法被认为很重要,所以我试图设想如何将它用于我想做的事情,但没有看到如何。
我正在使用 Selenium 在 python 中编写一个网络爬虫。可以为不同的客户端访问一些数据表,我希望我的程序的未来用户可以拉一个(或多个)表来查看数据,或者使用它来验证事情是否正确填充在网站。
该代码仍在进行中,我正在尝试学习最佳实践和正确的做事方式。欢迎任何其他反馈,我想学习。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
import getpass
import bs4
import time
###Open a headless Chrome, grab the URL page, enter into username and password, POST
chop = Options()
driver = input().strip()
if driver == "y":
chop.add_argument("--headless")
driver = webdriver.Chrome(r"<Path to Chromedriver.exe placeholder>", options=chop)
driver.get("<URL placeholder>")
element = driver.find_element_by_name("email")
element.clear()
element.send_keys(input("Username: ").strip())
element = driver.find_element_by_name("password")
element.clear()
element.send_keys(getpass.getpass().strip())
element.send_keys(Keys.ENTER)
###Select a client, navigate to a table
select = Select(driver.find_element_by_id("<ID placeholder>"))
select.select_by_value(input("Client #:").strip())
element = driver.find_element_by_id("<ID placeholder>")
element.click()
element = driver.find_element_by_id("<ID placeholder>")
element.click()
###Attempt to grab the entire table, print it out in terminal
###1 second sleep semi-necessary to give page time to load table
time.sleep(1)
element = driver.find_elements(By.TAG_NAME, "tr")
###Print out grabbed rows
for L in element[2:-2]:
print(L.text)
driver.quit()
到目前为止,它只允许您导航到其中一个表并获取所有行。有些行不是真的有效,所以这就是我切片的原因。占位符只是为了隐藏我实际工作的内容,不要认为公司希望一群随机的人找到该网站。
解决方案
selenium
已经使用面向对象的方法实现。OOP 旨在帮助减少尝试扩展具有额外要求的项目的压力,或者在您的情况下,假设我想抓取一个额外的网站,您必须为每个网站编写一个独特的脚本。我抽象的一种方法selenium
是创建一个控制器来管理所有开销selenium
,然后用一个解析器列表进行初始化,这些解析器负责抓取各个网站并返回它们的结果。这可能用代码更好地解释:
class WebParser:
def parse(browser: webdriver.Firefox):
# A unique script for handling this particular webpage
...
class SeleniumController:
def __init__(parsers: list[WebParser]):
self.parsers = parsers
self.browser = webdriver.FireFox()
# Finish initializing browser either here, or in a separate function
...
def trigger():
result = []
for p in self.parsers:
result.append(p.parse(self.browser))
# Handle your results
...
WebParser
然后,您可以为需要解析的每个不同网页创建一个子类。
这种问题也可能有益于使用适配器模式或某种抽象工厂来帮助在运行时创建 Web 解析器的形式。 refactoring.guru是一个将面向对象概念应用于不同类型问题的令人惊叹的站点
推荐阅读
- python - 无法将 JSON 数据插入 sqlite3 数据库
- java - 我如何计算达到某个列出的货币价值需要多少钞票
- google-vault-api - 获取 G-Suit 中特定帐户的物品数量和物品大小
- mysql - Amazon RDS MS Access 表在排序时显示错误结果
- node.js - 1 在 Node JS 中编辑 PowerPoint 图表的数据 & 2 推荐的文件存储
- reactjs - 在 React 中同时更新 React
- javascript - Nuxt 路由器在页面重新加载后导致错误的链接
- javascript - 动态设置 iFrame 的高度不起作用
- javascript - 即使表单无效,jQuery Validation 也会提交
- asp.net-core - 控制台主机中的 SignalR 服务器未发送保活