Очистка страницы с помощью генератора

#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.

4. domaintyper.com/top-websites/…

Ответ №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