Невозможно различить два выражения, которые должны работать одинаково - PullRequest
0 голосов
/ 09 июня 2019

Несколько дней назад я создал этот пост , чтобы найти какое-либо решение о том, как я могу позволить своему сценарию зацикливаться таким образом, чтобы сценарийбудет использовать несколько ссылок, чтобы проверить, является ли мой определенный title (который должен быть извлечен из каждой ссылки) ничем для four раз.Если title по-прежнему ничего не значит, сценарий break loop и перейдет к другой ссылке, чтобы повторить то же самое.

Вот как я добился успеха - ► Изменяя fetch_data(link) наreturn fetch_data(link) и определение counter=0 снаружи while loop, но внутри оператора if.

Исправленный сценарий:

import time
import requests
from bs4 import BeautifulSoup

links = [
    "https://stackoverflow.com/questions/tagged/web-scraping?sort=newest&page=2",
    "https://stackoverflow.com/questions/tagged/web-scraping?sort=newest&page=3",
    "https://stackoverflow.com/questions/tagged/web-scraping?sort=newest&page=4"
]
counter = 0

def fetch_data(link):
    global counter
    res = requests.get(link)
    soup = BeautifulSoup(res.text,"lxml")
    try:
        title = soup.select_one("p.tcode").text
    except AttributeError: title = ""

    if not title:
        while counter<=3:
            time.sleep(1)
            print("trying {} times".format(counter))
            counter += 1
            return fetch_data(link) #First fix
        counter=0 #Second fix

    print("tried with this link:",link)

if __name__ == '__main__':
    for link in links:
        fetch_data(link)

Это вывод, который приведенный выше сценарий производит (по желанию):

trying 0 times
trying 1 times
trying 2 times
trying 3 times
tried with this link: https://stackoverflow.com/questions/tagged/web-scraping?sort=newest&page=2
trying 0 times
trying 1 times
trying 2 times
trying 3 times
tried with this link: https://stackoverflow.com/questions/tagged/web-scraping?sort=newest&page=3
trying 0 times
trying 1 times
trying 2 times
trying 3 times
tried with this link: https://stackoverflow.com/questions/tagged/web-scraping?sort=newest&page=4

I used wrong selector within my script so that I can let it meet the condition I've defined above.

Почему я должен использовать return fetch_data(link) вместо fetch_data(link), поскольку выражения работают одинаково большую часть времени?

1 Ответ

1 голос
/ 09 июня 2019

Цикл while внутри вашей функции инициирует рекурсивный вызов, если он не может извлечь заголовок. Он работает, когда вы используете return fetch_data(link), так как всякий раз, когда счетчик меньше или равен 3 while counter<=3, он сразу же завершает функцию в конце цикла while, таким образом, не спускаясь к нижней строке, которая будет сбрасывать счетчик. до 0 counter=0. Поскольку счетчик является глобальной переменной и увеличивается только на 1 для каждой глубины рекурсии, у вас будет только максимум 4 глубины рекурсии, поскольку в любое время counter больше 3, он не будет переходить в цикл while, который будет вызывать другой fetch_data(link).

fetch_data (counter=0)
  --> fetch_data (counter=1)
    --> fetch_data (counter=2)
      --> fetch_data (counter=3)
        --> fetch_data (counter=4) 
        - not go into while loop, reset counter, print url
        - return to above function
      - return to above function
    - return to above function
  - return to above function

Если вы используете fetch_data(link), функция все равно будет инициировать рекурсивный вызов в цикле while. Однако не выходите сразу и сбросите счетчик на 0. Это опасно, потому что после того, как ваш счетчик перейдет к 4, функция и возврат к циклу while предыдущего вызова функции внутри цикла while, цикл while не будет прерываться и продолжайте инициировать дополнительные рекурсивные вызовы, потому что счетчик в настоящее время установлен на 0, что составляет <= 3. Это в конечном итоге достигнет максимальной глубины рекурсии и приведет к сбою программы. </p>

fetch_data (counter=0)
  --> fetch_data (counter=1)
    --> fetch_data (counter=2)
      --> fetch_data (counter=3)
        --> fetch_data (counter=4) 
        - not go into while loop, !!!reset counter!!!, print url
        - return to above function
      - not return to above function call
      - since counter = 0, continue the while loop
        --> fetch_data (counter=1)
          --> fetch_data (counter=2)
            --> fetch_data (counter=3)
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...