#python #web-scraping #beautifulsoup
#python #очистка веб-страниц #beautifulsoup
Вопрос:
Я пытаюсь получить все комментарии от пользователя reddit с помощью beautifulsoup. Вот код:
from urllib.request import urlopen as ureq
from bs4 import BeautifulSoup as soup
url = "https://www.reddit.com/user/IHateTheLetterF/"
client = ureq(url)
page_html = client.read()
pagesoup = soup(page_html, "html5lib")
comments = pagesoup.findAll("p",{"class":"_1qeIAgB0cPwnLhDF9XSiJM"})
Это работает, если я пытаюсь получить некоторые комментарии, но по какой-то причине он извлекает только 16 комментариев, а у пользователя явно больше 16 комментариев. Я пробовал использовать разные анализаторы, такие как lxml, html.parser и html5lib, но все они извлекают только 16 комментариев. Как ни странно, тот же самый код вчера получил 22 комментария. Любая помощь будет оценена
Ответ №1:
Это происходит потому, что страница использует динамический javascript для загрузки содержимого комментария. Поэтому вы не сможете выполнить это с помощью ureq
.
Вместо этого вы должны использовать selenium с webdriver для загрузки всех комментариев перед очисткой.
Вы можете попробовать загрузить исполняемый файл ChromeDriver здесь . И если вы вставите его в ту же папку, что и ваш скрипт, вы можете запустить:
Редактировать: использование скроллера custon для принудительной загрузки новых комментариев на страницу
import os
import time
from selenium import webdriver
from bs4 import BeautifulSoup
# configure driver
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--headless")
chrome_driver = os.getcwd() "\chromedriver.exe"
driver = webdriver.Chrome(options=chrome_options, executable_path=chrome_driver)
url = "https://www.reddit.com/user/IHateTheLetterF/comments/"
driver.get(url)
scroll_pause_time = 3 # You can try with your own pause time.
screen_height = driver.execute_script("return window.screen.height;") # get screen height
i = 1
while True:
driver.execute_script("window.scrollTo(0, {screen_height}*{i});".format(screen_height=screen_height, i=i)) # scroll screen height
i = 1 # times looped
time.sleep(scroll_pause_time) # wait content to load
scroll_height = driver.execute_script("return document.body.scrollHeight;") # check current scroll height
# Check your content
soup = BeautifulSoup(driver.page_source, "html.parser")
comments = soup.findAll("p", {"class": "_1qeIAgB0cPwnLhDF9XSiJM"})
print(len(comments))
# Finish loops when you cant scroll anymore
if (screen_height) * i > scroll_height:
break
Я позволил ему работать в течение нескольких минут и уже получил более 200 комментариев.
Хотя это может сработать, я предлагаю вам поискать propper API для этого.
Комментарии:
1. Это, безусловно, лучше, чем раньше, но очевидно, что у пользователя более 60 комментариев?
2. По-видимому, reddit использует бесконечную систему прокрутки. Я отредактирую ответ, чтобы создать пользовательский скроллер, но вам следует проверить наличие API-интерфейсов propper