我尝试使用Selenium的Webdriver.execute_script()来获取Reddit主页上的元素列表。 (在你推荐PRAW之前:Reddit实际上并不是我想要的元素,我只是以它为例。)
即使我在Chrome的开发工具控制台中运行我执行的脚本工作正常,但Selenium的方法只返回一个空列表,应该使用Reddit帖子的标题元素填充。
import urllib
from selenium import webdriver
from BeautifulSoup import BeautifulSoup
#Path to the chromedriver is definitely working fine.
path_to_chromedriver = 'C:\Path\goes\here\chromedriver.exe'
browser = webdriver.Chrome(executable_path = path_to_chromedriver)
url = 'http://www.reddit.com/'
browser.implicitly_wait(10)
browser.get(url)
code = 'document.getElementsByClassName("title may-blank loggedin")'
content = browser.execute_script("return "+code)
if len(content) == 0:
print content
else:
print len(content)
browser.quit()
我也尝试过使用webdriver.set_script_timeout()和webdriver.set_page_load_timeout()方法。
目标元素的示例:
<a class="title may-blank loggedin" href="/r/IAmA/comments/2necex/i_am_joel_hodgson_creator_of_mystery_science/" tabindex="1">I am Joel Hodgson, creator of Mystery Science Theater 3000, why don't you come at me?</a>
答案 0 :(得分:0)
一些问题。
不要使用JS来查找元素,这与Selenium的观点完全相反。
其次,你对CSS选择器和背后的选择有一些误解。类名选择器是。
第三,再加上上述内容,您的JS脚本不是CSS选择器。 getElementsByClassName
非常不同,只会返回匹配所有这些类的内容。
第四,在你的评论中,你已经将这个类名拼凑在一起。我假设这是因为在那里有空格会抛出一个复合类错误。这是正确的,应该指出上面的前三个问题。现在你已经将它们全部组合成一个字符串,它现在甚至不再与你拥有的原始代码相关 - 它只返回那些titlemay-blankloggedin
作为类的元素(显然,没有!)。
解决方案?我建议将Selenium用于它的意图以及它内置的定位策略。
browser.find_element_by_css_selector('a.title.may-blank.loggedin')
(选择器可以变得不那么脆弱,但我是故意这样做的,所以你可以看到效果)。
CSS选择器中的.
将作为和运算符(一个类title
和类的锚元素may-blank
和一类logged-in
。)
答案 1 :(得分:0)
您与execute_script
一起使用的JavaScript应该有效。
但是,正如班级loggedin
建议的那样,除非您实际登录到网站,否则任何元素都不会与loggedin
类匹配。当您启动新的Selenium实例时,它未登录,因此您将找不到loggedin
类的任何元素。修改您的代码,从loggedin
来电中删除getElementsByClassName
,您将获得匹配元素的列表。
使用execute_script
还是find_element...
并不重要。在您登录之前,任何元素都不会与类loggedin
匹配。虽然有时候使用execute_script
查找元素有很好的理由,但我认为没有充分的理由使用execute_script
1}} 在这种情况下所以我建议像
browser.find_elements_by_css_selector('.title.may-blank')
没有loggedin
类。这将返回具有title
和may-blank
类的所有元素。