Как очистить только новые ссылки (после предыдущей очистки) Использование Python

#python #web-scraping #beautifulsoup

#python #Очистка веб-страниц #beautifulsoup

Вопрос:

Я очищаю и загружаю ссылки с веб-сайта, и веб-сайт обновляется новыми ссылками каждый день. Мне бы хотелось, чтобы при каждом запуске моего кода он только очищал / загружал обновленные ссылки с момента последнего запуска программы, а не повторял весь код заново.

Я попытался добавить ранее очищенные ссылки в пустой список и выполнить остальную часть кода (который загружает и переименовывает файл), только если очищенная ссылка не найдена в списке. Но, похоже, это работает не так, как хотелось бы, потому что каждый раз, когда я запускаю код, он запускается «с 0» и перезаписывает ранее загруженные файлы.

Есть ли другой подход, который я должен попробовать?

Вот мой код (также открыт для общих предложений о том, как это очистить и улучшить)

 import praw
import requests
from bs4 import BeautifulSoup
import urllib.request
from difflib import get_close_matches
import os

period = '2018 Q4'
url = 'https://old.reddit.com/r/test/comments/b71ug1/testpostr23432432/'
headers = {'User-Agent': 'Mozilla/5.0'}
page = requests.get(url, headers=headers)

#set soup
soup = BeautifulSoup(page.text, 'html.parser')
table = soup.find_all('table')[0]

#create list of desired file names from existing directory names
candidates = os.listdir('/Users/test/Desktop/Test')
#set directory to download scraped files to
downloads_folder = '/Users/test/Desktop/Python/project/downloaded_files/'

#create empty list of names
scraped_name_list = []

#scrape site for names and links
for anchor in table.findAll('a'):
    try:
        if not anchor:
            continue
        name = anchor.text
        letter_link = anchor['href']
    #if name doesn't exist in list of names: append it to the list, download it, and rename it
        if name not in scraped_name_list:
            #append it to name list
            scraped_name_list.append(name)
            #download it
            urllib.request.urlretrieve(letter_link, '/Users/test/Desktop/Python/project/downloaded_files/'   period   " "   name   '.pdf')
            #rename it
            best_options = get_close_matches(name, candidates, n=1, cutoff=.33)
            try:
                if best_options:
                    name = (downloads_folder   period   " "   name   ".pdf")
                    os.rename(name, downloads_folder   period   " "   best_options[0]   ".pdf")
            except:
                pass
    except:
        pass
    #else skip it
    else:
        pass
  

Ответ №1:

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

вместо определения scraped_name_list = [] попробуйте что-то вроде этого

 try:
    with open('/path/to/your/stuff/scraped_name_list.lst', 'rb') as f:
        scraped_name_list = pickle.load(f)
except IOError:
    scraped_name_list = []
  

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

 with open('/path/to/your/stuff/scraped_name_list.lst', 'wb') as f:
    pickle.dump(scraped_name_list, f)
  

Комментарии:

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

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

3. спасибо, и это имеет смысл. Извините, если это глупый вопрос, но при первом запуске он, похоже, работает так, как ожидалось, с scraped_name_list.lst' созданием. Но при последующем запуске я получаю UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte . Полный путь with open('/Users/test/Desktop/scraped_name_list.lst', 'wb') as f: pickle.dump(scraped_name_list, f) . Нужно ли мне использовать другое расширение / тип файла? Если это имеет значение, я на macOS 10.14.5.

4. На самом деле, я думаю, что я понял это. Изменение 'r' на 'rb' , похоже, делает свое дело.

5. @MSD упс. да, я пропустил b . сейчас редактирую свой ответ.