#python #web-scraping #beautifulsoup #generator
#python #очистка веб-страниц #beautifulsoup #генератор
Вопрос:
Я очищаю сайт с помощью прекрасного супа. Проблема, с которой я сталкиваюсь, заключается в том, что определенные части сайта разбиты на страницы с помощью JS с неизвестным (изменяющимся) количеством страниц для очистки.
Я пытаюсь обойти это с помощью генератора, но я пишу его впервые, и мне трудно обдумать это и понять, имеет ли смысл то, что я делаю.
Код:
from bs4 import BeautifulSoup
import urllib
import urllib2
import jabba_webkit as jw
import csv
import string
import re
import time
tlds = csv.reader(open("top_level_domains.csv", 'r'), delimiter=';')
sites = csv.writer(open("websites_to_scrape.csv", "w"), delimiter=',')
tld = "uz"
has_next = True
page = 0
def create_link(tld, page):
if page == 0:
link = "https://domaintyper.com/top-websites/most-popular-websites-with-" tld "-domain"
else:
link = "https://domaintyper.com/top-websites/most-popular-websites-with-" tld "-domain/page/" repr(page)
return link
def check_for_next(soup):
disabled_nav = soup.find(class_="pagingDivDisabled")
if disabled_nav:
if "Next" in disabled_nav:
return False
else:
return True
else:
return True
def make_soup(link):
html = jw.get_page(link)
soup = BeautifulSoup(html, "lxml")
return soup
def all_the_pages(counter):
while True:
link = create_link(tld, counter)
soup = make_soup(link)
if check_for_next(soup) == True:
yield counter
else:
break
counter = 1
def scrape_page(soup):
table = soup.find('table', {'class': 'rankTable'})
th = table.find('tbody')
test = th.find_all("td")
correct_cells = range(1,len(test),3)
for cell in correct_cells:
#print test[cell]
url = repr(test[cell])
content = re.sub("<[^>]*>", "", url)
sites.writerow([tld] [content])
def main():
for page in all_the_pages(0):
print page
link = create_link(tld, page)
print link
soup = make_soup(link)
scrape_page(soup)
main()
Мои размышления о коде:
Скребок должен получить страницу, определить, есть ли следующая страница, очистить текущую страницу и перейти к следующей, повторив процесс. Если следующей страницы нет, она должна остановиться. Имеет ли это смысл, как я собираюсь это сделать здесь?
Комментарии:
1. вы можете использовать selenium для загрузки содержимого JS, поиска навигационных кнопок и по-прежнему анализировать содержимое HTML с помощью BS4.
2. синтаксический анализ работает, проблема не в JS. проблема в том, что я понятия не имею, как часто «нажимать далее». Я пытаюсь сделать это, проверяя, есть ли еще кнопка «далее» каждый раз, когда я очищаю страницу. Если есть, я хочу очистить эту следующую страницу, если нет, я хочу разорвать.
3. поделитесь URL-адресом, где я вижу, как выглядит HTML.
Ответ №1:
Как я уже говорил, вы могли бы использовать selenium для программного нажатия на Next
кнопку, но поскольку это не вариант для вас, я могу придумать следующий метод получения количества страниц с использованием чистого BS4:
import requests
from bs4 import BeautifulSoup
def page_count():
pages = 1
url = "https://domaintyper.com/top-websites/most-popular-websites-with-uz-domain/page/{}"
while True:
html = requests.get(url.format(pages)).content
soup = BeautifulSoup(html)
table = soup.find('table', {'class': 'rankTable'})
if len(table.find_all('tr')) <= 1:
return pages
pages = 1