如何使用 Selenium 和 Python 在 Python class 中调用方法

How to call a method within a Python class using Selenium and Python

我对编码很陌生,我需要解决一件实际的事情,只需从站点获取信息并将其写入 excel(我希望我可以通过指南进行管理),但主要问题我只是无法进入网站(该网站是免费的) 你能看看我的代码吗?当我 运行 它时,我得到

[] 进程已结束,退出代码为 0

import requests
from bs4 import BeautifulSoup
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

URL ='http://way2drug.com/passonline/'
HEADERS= {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'}


class Test1():
  def setup_method(self, method):
    self.driver = webdriver.Chrome()
    self.vars = {}
  
  def teardown_method(self, method):
    self.driver.quit()
  
  def test_1(self):
    # Test name: 1
    # Step # | name | target | value | comment
    # 1 | open | /passonline/ |  | 
    self.driver.get("http://way2drug.com/passonline/")
    # 2 | setWindowSize | 1920x1030 |  | 
    self.driver.set_window_size(1920, 1030)
    # 3 | click | css=#registration img |  | 
    self.driver.find_element(By.CSS_SELECTOR, "#registration img").click()
    # 4 | click | name=user_login |  | 
    self.driver.find_element(By.NAME, "user_login").click()
    # 5 | type | name=user_login |  | 
    self.driver.find_element(By.NAME, "user_login").send_keys("MY USER")
    # 6 | click | id=page1 |  | 
    self.driver.find_element(By.ID, "page1").click()
    # 7 | type | name=user_password |  | 
    self.driver.find_element(By.NAME, "user_password").send_keys("MY PASS")
    # 8 | click | id=register |  | 
    self.driver.find_element(By.ID, "register").click()
    # 9 | click | id=myHeader1 |  | 
    self.driver.find_element(By.ID, "myHeader1").click()
    # 10 | click | id=smiles |  | 
    self.driver.find_element(By.ID, "smiles").click()
    self.driver.find_element(By.ID, "smi").click()
    self.driver.find_element(By.ID, "smi").send_keys("CC1(C)C(O)CC[C@@]2(C)C1CC[C@]3(C)C2CCC4[C@@]3(C)CC[C@]5(C(O)=O)C4[C@H](C)C(C)=CC5")
    self.driver.find_element(By.CSS_SELECTOR, "#myContent4 input:nth-child(4)").click()



def get_html(url, params=None):
  r = requests.get(url, headers=HEADERS, params=params)
  return r

def get_content(html):
  soup = BeautifulSoup(html, 'html.parser')
  items = soup.find_all('a', class_='Antineoplastic')

  print(items)

def parse():
  html = get_html(URL)
  if html.status_code == 200:
    get_content(html.text)
  else:
    print('ALL YOUR BASE ARE BELONG TO US')


parse()

请注意 - 永远不要提供凭据

会发生什么?

你提到你必须执行登录,selenium 是一个不错的选择,但你正在做的是调用 parse(),它只通过 requests 执行调用。因此,如果您查看 soup,您将找不到您要找的东西。

如何修复?

执行您的 selenium 操作并走到您要抓取的网站。在下一步中,将您的 driver.page_source 推入 BeautifulSoup 并找到您的元素:

soup = BeautifulSoup(driver.page_source,'html.parser')
items = soup.find_all('a', class_='Antineoplastic')

print(items)

如果你的选择是正确的,你会得到你的结果。

编辑

关于您的评论,您可以找到最终的线索,对于中间的调试步骤,您应该提出带有重点示例的新问题:

import requests
from bs4 import BeautifulSoup
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

driver = webdriver.Chrome()
 
driver.get("http://way2drug.com/passonline/")
driver.set_window_size(1920, 1030)
driver.find_element(By.CSS_SELECTOR, "#registration img").click()
driver.find_element(By.NAME, "user_login").click()
driver.find_element(By.NAME, "user_login").send_keys("MY USER")
driver.find_element(By.ID, "page1").click()
driver.find_element(By.NAME, "user_password").send_keys("MY PASS")
driver.find_element(By.ID, "register").click()
driver.find_element(By.ID, "myHeader1").click()
driver.find_element(By.ID, "smiles").click()
driver.find_element(By.ID, "smi").click()
driver.find_element(By.ID, "smi").send_keys("CC1(C)C(O)CC[C@@]2(C)C1CC[C@]3(C)C2CCC4[C@@]3(C)CC[C@]5(C(O)=O)C4[C@H](C)C(C)=CC5")
driver.find_element(By.CSS_SELECTOR, "#myContent4 input:nth-child(4)").click()

soup = BeautifulSoup(driver.page_source,'html.parser')
items = soup.find_all('a', class_='Antineoplastic')

print(items)

driver.quit()

使用 时,您必须注意以下几点:

  • 定义 class 方法后,您必须在 main 中创建 class 的实例以调用这些方法如下:

    test1 = Test1()
    test1.setup_method()
    
  • 在定义方法时,参数需要与作为参数从 main 传递的参数 number/type 相匹配。例如:

    def test_1(self):
    

    应称为:

    test1.test_1()
    

这个用例

我从你的整个代码块中提取了几个块并做了一些修改来演示 Classes 的 implementation/usage:

代码块:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

class Test1():
  def setup_method(self):
    print("Within setup_method")
    s = Service('C:\BrowserDrivers\chromedriver.exe')
    self.driver = webdriver.Chrome(service=s)


  def teardown_method(self):
    print("Within teardown_method")
    self.driver.quit()

  def test_1(self):
    print("Within test_1") 
    self.driver.get("http://way2drug.com/passonline/")


test1 = Test1()
test1.setup_method()
test1.test_1()
test1.teardown_method()

控制台输出:

Within setup_method
Within test_1
Within teardown_method

参考资料

您可以在以下位置找到一些相关的详细讨论:

  • How to execute testcases through Python Class using Selenium