首页 > 解决方案 > 面向对象的方法是否适合我的任务?如果是这样,关于如何实施它的粗略想法?

问题描述

目前正在尝试为我的工作开发一些可以被其他人使用的东西。我知道面向对象的方法被认为很重要,所以我试图设想如何将它用于我想做的事情,但没有看到如何。

我正在使用 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()

到目前为止,它只允许您导航到其中一个表并获取所有行。有些行不是真的有效,所以这就是我切片的原因。占位符只是为了隐藏我实际工作的内容,不要认为公司希望一群随机的人找到该网站。

标签: python-3.xselenium

解决方案


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是一个将面向对象概念应用于不同类型问题的令人惊叹的站点


推荐阅读