我正在开发一个需要位自动化和网络报废的项目,我正在使用 Selenium 和 BeautifulSoup(python2.7)。
我想打开只有一个网络浏览器实例并登录网站,保持该会话,我正在尝试打开新标签,这些标签将被独立控制通过线程,控制选项卡的每个线程并执行自己的任务。我该怎么办?一个示例代码会很好。那么这是我的代码:
def threadFunc(driver, tabId):
if tabId == 1:
#open a new tab and do something in it
elif tabId == 2:
#open another new tab with some different link and perform some task
.... #other cases
class tabThreads(threading.Thread):
def __init__(self, driver, tabId):
threading.Thread.__init__(self)
self.tabID = tabId
self.driver = driver
def run(self):
print "Executing tab ", self.tabID
threadFunc(self.driver, self.tabID)
def func():
# Created a main window
driver = webdriver.Firefox()
driver.get("...someLink...")
# This is the part where i am stuck, whether to create threads and send
# them the same web-driver to stick with the current session by using the
# javascript call "window.open('')" or use a separate for each tab to
# operate on individual pages, but that will open a new browser instance
# everytime a driver is created
thread1 = tabThreads(driver, 1)
thread2 = tabThreads(driver, 2)
...... #other threads
如果需要,我愿意接受使用任何其他模块的建议
答案 0 :(得分:0)
我的理解是Selenium驱动程序不是线程安全的。在WebDriver规范中,“线程安全”部分是空的......我认为它们根本没有涉及该主题。 https://www.w3.org/TR/2012/WD-webdriver-20120710/#thread-safety
因此,虽然您可以与多个线程共享驱动程序引用并从多个线程调用驱动程序,但无法保证驱动程序能够正确处理多个异步调用。
相反,您必须同步来自多个线程的调用以确保在下次启动之前完成一个调用,或者您应该只有一个线程进行Selenium API调用...可能处理来自多个其他线程填充的队列的命令
答案 1 :(得分:0)
如果您正在使用脚本自动提交表单(简而言之,就是执行GET和POST请求),建议您查看requests。您可以轻松地从浏览器(在Firefox和Chrome上的“开发人员窗格”中的网络选项卡)中捕获发布请求,然后提交它们。像这样:
session = requests.session()
response = session.get('https://stackoverflow.com/')
soup = BeautifulSoup(response.text)
甚至POST数据,例如:
postdata = {'username':'John','password':password}
response=session.post('example.com',data=postdata,allow_redirects=True)
它很容易实现线程化,比使用硒快很多倍,唯一的问题是没有JavaScript或Form支持,因此您需要使用老式的方法。
编辑: 还要看看ThreadPoolExecutor