所以我正在尝试使用 Python 登录 Quora,然后抓取一些东西。
我正在使用 Selenium 登录网站。这是我的代码:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get('http://www.quora.com/')
username = driver.find_element_by_name('email')
password = driver.find_element_by_name('password')
username.send_keys('email')
password.send_keys('password')
password.send_keys(Keys.RETURN)
driver.close()
现在问题:
找到并填写登录表单需要大约 4 分钟,速度非常慢。我可以做些什么来加快这个过程吗?
登录时,如何确保没有错误?换句话说,我如何检查响应代码?
如何使用 selenium 保存 cookie,以便我可以在登录后继续抓取?
如果没有办法让 selenium 更快,还有其他登录方法吗? (Quora 没有 API)
我遇到了类似的问题,使用 ChromeDriver 在 Python selenium 中调用 find_elements_xxx 非常慢。我最终将问题追查到我在 find_element_xxx() 调用之前进行的 driver.implicitly_wait() 调用;当我把它拿出来时,我的 find_element_xxx() 调用运行得很快。
现在,我 知道 当我调用 find_elements_xxx() 时那些元素就在那里。所以我无法想象为什么 implicit_wait 应该影响这些操作的速度,但确实如此。
去过,selenium很慢。填写表格可能不会慢到 4 分钟。然后我开始使用 phantomjs,它比 firefox 快得多,因为它是无头的。安装最新的 phantomjs 后,您可以简单地将 webdriver 行中的 Firefox() 替换为 PhantomJS()。
要检查您是否已登录,您可以断言登录后显示的某些元素。
只要您不退出驱动程序,cookies 将可用于跟踪链接
您可以尝试使用 urllib 并直接发布到登录链接。您可以使用 cookiejar 来保存 cookie。你甚至可以简单地保存 cookie,毕竟 cookie 只是 http header 中的一个字符串
您可以使用自己的 setAttribute 方法来加快表单填写速度,这里是 java 代码
public void setAttribute(By locator, String attribute, String value) {
((JavascriptExecutor) getDriver()).executeScript("arguments[0].setAttribute('" + attribute
+ "',arguments[1]);",
getElement(locator),
value);
}
无头运行网络驱动程序应该会在一定程度上提高其执行速度。
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options
options = Options()
options.add_argument('-headless')
browser = webdriver.Firefox(firefox_options=options)
browser.get('https://google.com/')
browser.close()
对于 Windows 7 和带有 Python Selenium 的 IEDRIVER,结束 Windows 命令行并重新启动它解决了我的问题。
我在使用 find_element..clicks 时遇到了麻烦。他们花了 30 秒加一点。这是我拥有的代码类型,包括捕获运行多长时间。
timeStamp = time.time()
elem = driver.find_element_by_css_selector(clickDown).click()
print("1 took:",time.time() - timeStamp)
timeStamp = time.time()
elem = driver.find_element_by_id("cSelect32").click()
print("2 took:",time.time() - timeStamp)
每次点击记录大约 31 秒。结束命令行并重新启动它(这确实会结束所有 IEDRIVERSERVER.exe 进程)后,每次点击需要 1 秒。
我已经更改了定位器,而且效果很快。此外,我还添加了使用 cookie 的功能。检查下面的代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
import pickle
driver = webdriver.Firefox()
driver.get('http://www.quora.com/')
wait = WebDriverWait(driver, 5)
username = wait.until(EC.presence_of_element_located((By.XPATH, '//div[@class="login"]//input[@name="email"]')))
password = wait.until(EC.presence_of_element_located((By.XPATH, '//div[@class="login"]//input[@name="password"]')))
username.send_keys('email')
password.send_keys('password')
password.send_keys(Keys.RETURN)
wait.until(EC.presence_of_element_located((By.XPATH, '//span[text()="Add Question"]'))) # checking that user logged in
pickle.dump( driver.get_cookies() , open("cookies.pkl","wb")) # saving cookies
driver.close()
我们已经保存了cookies,现在我们将在新的浏览器中应用它们:
driver = webdriver.Firefox()
driver.get('http://www.quora.com/')
cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
driver.add_cookie(cookie)
driver.get('http://www.quora.com/')
希望,这会有所帮助。
如果
driver.get()
很慢,这个答案是最快的选择,它从网络驱动程序中获取cookies和会话,并在请求中使用它来发出get
请求,这比网络驱动程序快得多。
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = webdriver.ChromeOptions()
options.add_argument("headless") # to stop opening new chrome browser on every hit
driver = webdriver.Chrome('chromedriver.exe', chrome_options=options) # download chromedriver and give the location
...
...
This section might include extra webdriver settings like:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, 'nav-global-location-popover-link'))).click()
...
...
#creating requests session
s = requests.Session()
# Set correct user agent
selenium_user_agent = driver.execute_script("return navigator.userAgent;")
s.headers.update({"user-agent": selenium_user_agent})
#setting cookies of webdriver to requests
for cookie in driver.get_cookies():
s.cookies.set(cookie['name'], cookie['value'], domain=cookie['domain'])
#get requests (much more faster than webdriver requests)
response = s.get('https://www.amazon.com/dp/B07F2LR8NX')
bs = BeautifulSoup(response.content, 'html.parser')
这个
requests.Session().get()
比driver.get()
快多了