Проблема:
Не знаю, повторяет ли меня Google-фу, но я не могу загрузить CSV-файлы из списка URL-адресов.Я использовал requests
и bs4
для сбора URL-адресов (окончательный список верен) - для получения дополнительной информации см. Процесс ниже.
Затем я следовал одному из приведенных здесь ответов, используя urllib
для загрузки: Попытка загрузки данных из URL с помощью файла CSV , а также ряда других ответов python для stackoverflow для загрузки csvs.
В настоящее время я застрял с
Ошибка HTTP 404: не найдено
(ниже трассировки стека от последней попытки, где проходил пользователь-агент)
----> 9 f = urllib.request.urlopen(req)
10 print(f.read().decode('utf-8'))
#other lines
--> 650 raise HTTPError(req.full_url, code, msg, hdrs, fp)
651
652 class HTTPRedirectHandler(BaseHandler):
HTTPError: HTTP Error 404: Not Found
Я пробовал решение здесь добавить User-Agent
: Web Scraping с использованием Python, выдающий ошибку HTTP 404: не найдено , хотя я ожидал бы код ошибки 403, а не 404 - но, похоже, сработал для ряда OP.
Это все ещене удалось с той же ошибкой.Я почти уверен, что смогу решить эту проблему, просто используя selenium и передав URL-адреса csv в .get, но я хочу знать, смогу ли я решить эту проблему только с помощью запросов.
Краткое содержание:
Я захожу на эту страницу:
https://digital.nhs.uk/data-and-information/publications/statistical/patients-registered-at-a-gp-practice
Я беру все ссылки на ежемесячные версии, например, Patients Registered at a GP Practice May 2019
, затем я посещаю каждую из этих страниц и беру всеcsv ссылки внутри.
Я зацикливаю последний словарь из filename:download_url
пар, пытающихся загрузить файлы.
Вопрос:
Кто-нибудь может увидеть, что я делаю неправильно или как это исправить, чтобы я мог скачивать файлы, не прибегая к селену?Я также не уверен в самом эффективном способе сделать это - возможно, urllib на самом деле вообще не требуется, и достаточно просто запросов?
Python:
Без user-agent:
import requests
from bs4 import BeautifulSoup as bs
import urllib
base = 'https://digital.nhs.uk/'
all_files = []
with requests.Session() as s:
r = s.get('https://digital.nhs.uk/data-and-information/publications/statistical/patients-registered-at-a-gp-practice')
soup = bs(r.content, 'lxml')
links = [base + item['href'] for item in soup.select('.cta__button')]
for link in links:
r = s.get(link)
soup = bs(r.content, 'lxml')
file_links = {item.text.strip().split('\n')[0]:base + item['href'] for item in soup.select('[href$=".csv"]')}
if file_links:
all_files.append(file_links) #ignore empty dicts as for some months there is no data yet
else:
print('no data : ' + link)
all_files = {k: v for d in all_files for k, v in d.items()} #flatten list of dicts to single dict
path = r'C:\Users\User\Desktop'
for k,v in all_files.items():
#print(k,v)
print(v)
response = urllib.request.urlopen(v)
html = response.read()
with open(path + '\\' + k + '.csv', 'wb') as f:
f.write(html)
break #as only need one test case
Тест с добавлением User-Agent:
req = urllib.request.Request(
v,
data=None,
headers={
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'
}
)
f = urllib.request.urlopen(req)
print(f.read().decode('utf-8'))