Пропустить ссылку из списка при очистке части с помощью python

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

Следующий цикл предназначен для загрузки текста, содержащегося в списке URL-адресов (3 в примере). Он делает это для всех ссылок, кроме этой (этой), третий в примере занимает очень много времени. Открыв его в браузере, он выглядит так, будто в нем есть несколько изображений jpg. (текст представляет собой количество документов, объединенных в 1 файл; в этом конкретном примере некоторые из документов были изображениями).

Изображения можно распознать в тексте благодаря этим строкам перед ними:

<DOCUMENT>
<TYPE>GRAPHIC
<SEQUENCE>7
<FILENAME>tex99-4_pg01.jpg
<DESCRIPTION>GRAPHIC
<TEXT>
begin 644 tex99-4_pg01.jpg

и за ними следует этот код:

end
</TEXT>
</DOCUMENT>

Есть ли способ ПРОПУСТИТЬ эту ссылку, если загрузка занимает слишком много времени, чтобы сделать парсер быстрее? Я хочу применить этот код к 320 КБ этих ссылок и хотел бы найти способ ускорить загрузку, а не «обрезать» txt, который я получаю впоследствии.

Это то, что я сейчас использую для очистки:

import pandas as pd
import requests

list_of_links = ['https://www.sec.gov/Archives/edgar/data/1000298/0001193125-14-321757.txt',  
                 'https://www.sec.gov/Archives/edgar/data/1002225/0000903423-14-000495.txt', 
                 'https://www.sec.gov/Archives/edgar/data/1004724/0001144204-14-042745.txt'] # the one with the images
number_of_urls = len(list_of_links)  # get number of links to iterate them
i = 0         

column_names = ["Filing text"]
DF = pd.DataFrame(columns = column_names)

while i < number_of_urls: 
    print("File #", i+1,"\tis being processed") # print this to visually see how long each download takes
    DF.loc[i, "Filing text"] = requests.get(list_of_links[i]).text
    i += 1

person Alessandro Chiavari    schedule 14.05.2020    source источник
comment
о, чувак - не добавляй так к своему фрейму данных. Заполнять поздно при создании экземпляра: pandas.DataFrame([requests.get(link).text for link in list_of_links], columns=columns_names)   -  person Paul H    schedule 14.05.2020


Ответы (1)


Для библиотеки requests вы можете проверить этот ответ: https://stackoverflow.com/a/22347526/8294752

В вашем случае, поскольку это всегда просто текстовые данные, достаточно посмотреть длину содержимого.

С другой стороны, всегда рекомендуется включать timeout в вызов запросов. Это не решит вашу проблему, так как тайм-аут учитывает только время, в течение которого сервер не отвечает, но его отсутствие может создать проблемы, особенно в цикле.

ИЗМЕНИТЬ

Это может быть рабочим решением вашей проблемы (я также включил сюда отзывы Пола Х):

Обратите внимание, что я поменял местами второй и последний URL в списке, чтобы вы могли лучше оценить экономию времени. Кроме того, помните, что у вас будет некоторое None, если в конце df, и установите осмысленное CONTENT_LENGTH_LIMIT в зависимости от данных, которые вы хотите загрузить.

import pandas as pd
import requests

list_of_links = ['https://www.sec.gov/Archives/edgar/data/1000298/0001193125-14-321757.txt',
                 'https://www.sec.gov/Archives/edgar/data/1004724/0001144204-14-042745.txt',  
                 'https://www.sec.gov/Archives/edgar/data/1002225/0000903423-14-000495.txt', 
                 ] # the one with the images     

column_names = ["Filing text"]
DF = pd.DataFrame(columns = column_names)

CONTENT_LENGTH_LIMIT = 8070869 # just a limit which is lower than the size of the third link
def fetch_text(url):
    print("Url", url,"\tis being processed") # print this to visually see how long each download takes
    try:
        r = requests.get(url, stream=True, timeout=5)
        if int(r.headers.get('Content-Length')) > CONTENT_LENGTH_LIMIT:
            print("Url", url,"\thas been skipped")
            return None
        else: 
            text = "".encode() # the chunks are in bytes
            for chunk in r.iter_content(1024):
                text += chunk
        return text.decode()
    except requests.exceptions.Timeout as e:
        print("The server did not respond in time")
        # here it will return None, you can filter it later

DF = pd.DataFrame([fetch_text(link) for link in list_of_links],
                    columns=column_names)
person arabinelli    schedule 14.05.2020
comment
спасибо - отличный материал. включу это и посмотрю, смогу ли я решить - person Alessandro Chiavari; 14.05.2020
comment
@arabinelli - Спасибо, это выглядит потрясающе. - person zero; 15.05.2020
comment
Рад, что это полезно! - person arabinelli; 15.05.2020