Python: найти условие, чтобы выйти из цикла - PullRequest
0 голосов
/ 06 октября 2019

Цель моего кода - очистить таблицу, содержащую несколько страниц, в Интернете.

Пока что с использованием селена & bs4 мне удалось это сделать. Однако у меня возникают проблемы с выходом из цикла, поскольку на последней странице все еще есть кнопка «Далее», в результате программа продолжает снова и снова очищать последнюю страницу.

from selenium import webdriver
from bs4 import BeautifulSoup as bs
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
import csv
import datetime as dt

# website url
url = "https://poit.bolagsverket.se/poit/PublikSokKungorelse.do?method=redirect&forward=main.no.sidebar.sokresultat"

# website
driver = webdriver.Chrome()
driver.get(url)

# click sök kungörelse 
driver.find_element_by_xpath('//*[@id="nav1-2"]').click()

# click avancerad sökning 
driver.find_element_by_xpath('//*[@id="content"]/form/div[2]/a').click()

# select "annan period"
select = Select(driver.find_element_by_id('tidsperiod'))
select.select_by_value('6')

# select "skuldsanering"
select = Select(driver.find_element_by_id('amnesomrade'))
select.select_by_value('5')

# select "inledande av skuldsanering"
select = Select(driver.find_element_by_id('kungorelserubrik'))
select.select_by_value('29')

#calculate date
today = dt.date.today()
last_monday = str(today - dt.timedelta(days=7))
last_friday = str(today - dt.timedelta(days=3))

# insert search date
inputElement = driver.find_element_by_id("from")
inputElement.send_keys(last_monday)
inputElement = driver.find_element_by_id("tom")
inputElement.send_keys(last_friday)

# click on "sök"
driver.find_element_by_xpath('//*[@id="SokKungorelse"]').click()

#get updated url
html = driver.page_source

#scrape table
with open('skuldsanering.txt', 'w', encoding='utf-8') as r:
    while True:
        html = driver.page_source
        soup = bs(html, 'html.parser')
        table = soup.find('tbody')
        table_rows = table.find_all('tr')
        for tr in table_rows:
            td = tr.find_all('td')
            row = [i.get_text(strip=True) for i in td]
            csv_writer = csv.writer(r)
            csv_writer.writerows([row])
        try:
            driver.find_element_by_xpath('//*[@id="movenextTop"]').click()
            soup = bs(html, 'html.parser')
        except: 
            #insert condition to break out of loop
            break

Я подумал, может быть, возможно, можно было бы включить счетчик кликов и выйти из цикла, когда количество кликов (x) равно y на «странице x of y»? Если это хорошее решение, как мне двигаться дальше? Если нет, что было бы лучшим решением?

Заранее большое спасибо!

Ответы [ 2 ]

0 голосов
/ 06 октября 2019

Хммм, да, я не очень люблю извлекать номер страницы из необработанного текста - но, похоже, это самый удобный вариант - не могу придумать другой способ сделать это. Попробуйте это:

def main():

    from selenium import webdriver
    from selenium.webdriver.support.ui import Select
    from bs4 import BeautifulSoup
    import datetime as dt
    import re

    url = "https://poit.bolagsverket.se/poit/PublikSokKungorelse.do"

    driver = webdriver.Chrome()
    driver.get(url)

    driver.find_element_by_xpath('//*[@id="nav1-2"]').click()

    driver.find_element_by_xpath('//*[@id="content"]/form/div[2]/a').click()

    select = Select(driver.find_element_by_id('tidsperiod'))
    select.select_by_value('6')

    select = Select(driver.find_element_by_id('amnesomrade'))
    select.select_by_value('5')

    select = Select(driver.find_element_by_id('kungorelserubrik'))
    select.select_by_value('29')

    today = dt.date.today()
    last_monday = str(today - dt.timedelta(days=7))
    last_friday = str(today - dt.timedelta(days=3))

    inputElement = driver.find_element_by_id("from")
    inputElement.send_keys(last_monday)
    inputElement = driver.find_element_by_id("tom")
    inputElement.send_keys(last_friday)

    driver.find_element_by_xpath('//*[@id="SokKungorelse"]').click()

    while True:
        page = driver.page_source
        soup = BeautifulSoup(page, "html.parser")

        label = soup.find("em", {"class": "gotopagebuttons"}).get_text(strip=True)
        pattern = "Sida (\d+) av (\d+)"

        match = re.match(pattern, label)
        assert match is not None

        print(match.group())

        for row in soup.find("tbody").find_all("tr"):
            for td in row.find_all("td"):
                text = td.get_text(strip=True)
                print(" " * 4 + text)
        print(end="\n\n")

        if match.group(1) == match.group(2):
            # No more pages
            break

        driver.find_element_by_xpath('//*[@id="movenextTop"]').click()

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())
0 голосов
/ 06 октября 2019

Страница результатов показывает страницу x of y, вы можете проверить, если x == y каждый раз, и когда это правда, прерывать цикл.

Вот тег, о котором я говорю.

<em class="gotopagebuttons">Sida 17 av 17</em>

Вы можете разбить строку или попробовать регулярные выражения, чтобы получить оба номера страниц, а затем сравнить их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...