Ane*_*esh 0 python selenium python-3.x
我试图使用selenium与python刮取youtube评论.下面是只删除一个注释并抛出错误的代码
driver = webdriver.Chrome()
url="https://www.youtube.com/watch?v=MNltVQqJhRE"
driver.get(url)
wait(driver, 5500)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight + 500);")
driver.implicitly_wait(5000)
#content = driver.find_element_by_xpath('//*[@id="contents"]')
comm=driver.find_element_by_xpath('//div[@class="style-scope ytd-item-section-renderer"]')
comm1=comm.find_elements_by_xpath('//yt-formatted-string[@id="content-text"]')
#print(comm.text)
for i in range(50):
print(comm1[i].text,end=' ')
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出.如何获得该页面上的所有评论??? 谁能帮我这个.
Being a sucessful phyton freelancer really mean to me because if I able to make $2000 in month I can really help my family financial, improve my skill, and have a lot of time to refreshing. So thanks Qazi, you really help me :D
Traceback (most recent call last):
File "C:\Python36\programs\Web scrap\YT_Comm.py", line 19, in <module>
print(comm1[i].text,end=' ')
IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)
一个IndexError意味着你试图访问不存在的列表中的位置.您正在遍历元素列表(comm1)正好50次,但列表中的元素少于50个,因此最终您尝试访问不存在的索引.
从表面上看,您可以通过更改迭代来解决您的问题,以完全覆盖列表中存在的元素 - 不多也不少:
for element in comm1:
print(element.text, end=‘ ‘)
Run Code Online (Sandbox Code Playgroud)
但是,留给你的问题,为什么你的列表中有超过50个元素少.你正在搜索的视频有超过90条评论.为什么你的清单没有全部?
如果您查看浏览器中的页面,您将看到注释使用无限滚动技术逐步加载:当用户滚动到文档的底部时,将获取并呈现另一个"页面"注释,增加文件的长度.要加载更多注释,您需要触发此行为.
但是根据评论的数量,一次提取可能还不够.为了触发获取和呈现所有内容,您需要:
我们已经知道通过滚动到内容容器的底部(带有元素id #contents)来获取其他内容,所以让我们这样做:
driver.execute_script(
"window.scrollTo(0, document.querySelector('#contents').scrollHeight);")
Run Code Online (Sandbox Code Playgroud)
(注意:因为内容位于一个absolute位置元素中,所以document.body.scrollHeight将始终0并且不会触发滚动.)
但与任何浏览器自动化一样,我们正在与应用程序竞争:如果内容容器尚未呈现,该怎么办?我们的卷轴会失败.
Selenium提供WebDriverWait()帮助您等待应用程序处于特定状态.它还通过其expected_conditions模块提供一组等待的常见状态,例如元素的存在.我们可以使用这两个来等待内容容器存在:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
TIMEOUT_IN_SECONDS = 10
wait = WebDriverWait(driver, TIMEOUT_IN_SECONDS)
wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#contents")))
Run Code Online (Sandbox Code Playgroud)
在较高级别,我们可以确定是否通过以下方式获取其他内容:
在我们的容器(with id "#contents")中,每个内容都有id #content.要计算内容,我们可以简单地获取每个元素并使用Python的内置len():
count = len(driver.find_elements_by_css_selector("#contents #content")
Run Code Online (Sandbox Code Playgroud)
但同样,我们正在与应用程序竞争:如果获取或渲染其他内容的速度慢,会发生什么?我们不会马上看到它.
我们需要给Web应用程序时间来做它的事情.为此,我们可以使用WebDriverWait()自定义条件:
def get_count():
return len(driver.find_elements_by_css_selector("#contents #content"))
count = get_count()
# ...
wait.until(
lambda _: get_count() > count)
Run Code Online (Sandbox Code Playgroud)
但是,如果没有任何其他内容怎么办?我们等待计数增加将超时.
只要我们的超时足够高以允许有足够的时间来显示其他内容,我们就可以假设没有其他内容并忽略超时:
try:
wait.until(
lambda _: get_count() > count)
except TimeoutException:
# No additional content appeared. Abort our loop.
break
Run Code Online (Sandbox Code Playgroud)
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
TIMEOUT_IN_SECONDS = 10
wait = WebDriverWait(driver, TIMEOUT_IN_SECONDS)
driver.get(URL)
wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#contents")))
def get_count():
return len(driver.find_elements_by_css_selector("#contents #content"))
while True:
count = get_count()
driver.execute_script(
"window.scrollTo(0, document.querySelector('#contents').scrollHeight);")
try:
wait.until(
lambda _: get_count() > initial_count)
except TimeoutException:
# No additional content appeared. Abort our loop.
break
elements = driver.find_elements_by_css_selector("#contents #content")
Run Code Online (Sandbox Code Playgroud)
使用capybara-py,这变得有点简单:
import capybara
from capybara.dsl import page
from capybara.exceptions import ExpectationNotMet
@capybara.register_driver("selenium_chrome")
def init_selenium_chrome_driver(app):
from capybara.selenium.driver import Driver
return Driver(app, browser="chrome")
capybara.current_driver = "selenium_chrome"
capybara.default_max_wait_time = 10
page.visit(URL)
contents = page.find("#contents")
elements = []
while True:
try:
elements = contents.find_all("#content", minimum=len(elements) + 1)
except ExpectationNotMet:
# No additional content appeared. Abort our loop.
break
page.execute_script(
"window.scrollTo(0, arguments[0].scrollHeight);", contents)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
624 次 |
| 最近记录: |