Запустите Python Script, пока он не достигнет требуемого результата - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь очистить некоторые данные с веб-сайта, который через некоторое время динамически обновляется. это означает, что я очищаю некоторые HTML div, которые не существуют на странице каждый раз.

Я хочу получить из него число, скопировать его и вставить, когда захочу.

До сих пор я пытался сделать что-то подобное, что дает мне результат локально. но когда я делаю это онлайн, чтобы вычистить информацию с веб-сайта, это выдает мне ошибку, потому что этот элемент HTML не существует.

Я хочу, чтобы скрипт запускался даже после возникновения ошибки, потому что я уверен, что если он соответствует элементу, он выполнит свою работу.

Мой код:


from urllib.request import urlopen
from bs4 import BeautifulSoup
from bs4 import BeautifulSoup as soup  # HTML data structure
from urllib.request import urlopen as uReq  # Web client
import re
import time
import pyperclip


while True:

    page_url = "https://www.example.com/"

    uClient = uReq(page_url)

    page_soup = soup(uClient.read(), "html.parser")


    numbers = page_soup.find('div',{'id':'number-id'}).find('span').get_text()
    time.sleep(5*60)

Это дает мне эту ошибку.

  File "t.py", line 23, in <module>
    codes = page_soup.find('div',{'id':'number-id'}).find('span').get_text()
AttributeError: 'NoneType' object has no attribute 'get_text'

Может кто-нибудь помочь мне с вопрос

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Вместо того, чтобы делать все это в одной строке, я предлагаю вам сделать это шаг за шагом, с проверками, если все промежуточное значение определено. От:

numbers = page_soup.find('div',{'id':'number-id'}).find('span').get_text()

до

div = page_soup.find('div',{'id':'number-id'})
if div:
    span = div.find('span')
    if not span:
        # maybe sleep, increase attemts?
        continue
    numbers = span.get_text()
    ...

Поскольку суп возвращается None, если нет совпадения, поэтому вы пытаетесь вызвать None.get_text (..), что неправильно

Редактировать: изменил код для продолжения (не span) вместо div

Редактировать: весь код должен выглядеть следующим образом:

from bs4 import BeautifulSoup as soup  # HTML data structure
from urllib.request import urlopen  # Web client
import re
import time
import pyperclip

page_url = "https://www.example.com/"
while True:
    with urlopen(page_url) as response: # urlopen is a resource. with statement closes the resource after you stop using it.
        page_soup = soup(response.read(), "html.parser")

        if div := page_soup.find('div',{'id':'number-id'}):# see https://docs.python.org/3/whatsnew/3.8.html
            if span := div.find('span'): 
                numbers = span.get_text()
                match = re.search('\d{5,}', numbers)
                card = match.group(0)
                pyperclip.copy(card)
                pyperclip.paste()
                # break
    time.sleep(5*60)
0 голосов
/ 06 марта 2020

Вы можете использовать try и except, например,

try:
    numbers = page_soup.find('div',{'id':'number-id'}).find('span').get_text()
except:
    pass

Хотя наличие try и except в пределах while True l oop обычно не рекомендуется, так как скорее всего попадет в бесконечное л oop. Вы можете обойти это, добавив условие break, например

attempts=0

while True:
    if attempts==10:
        break
    page_url = "https://www.example.com/"

    uClient = uReq(page_url)

    page_soup = soup(uClient.read(), "html.parser")

    try:
        numbers = page_soup.find('div',{'id':'number-id'}).find('span').get_text()
        match = re.search('\d{5,}', numbers)
        card = match.group(0)
        pyperclip.copy(card)
        pyperclip.paste()
    except:
        attempts+=1


    time.sleep(5*60)

, которое не сможет работать до 10 раз, прежде чем вырваться из While l oop, просто измените if attempts==10: на большее число при необходимости.

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