как получить код html-страницы средствами Python?
В дополнение к другим ответам есть еще внешняя библиотека requests. У нее по мнению многих, в чье число и я вхожу, более красивый интерфейс чем у стандартных библиотек.
Простой страницы, динамически не меняющейся
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.3.13.43310
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Requests-HTML: The modern way of web scraping.
Python is an excellent tool in your toolbox and makes many tasks way easier, especially in data mining and manipulation. As a freelancer, people often come to me for the same reasons: Python’s difficult, the code is about as understandable as a bowl of spaghetti and generally inaccessible for beginners. “Why do I need 3 different libraries to download some data off a website?” This is very unfortunate since web scraping is something especially data scientists can use almost every day.
In this tutorial, I will show you the basics of web scraping with requests-html, the modern way of scraping data off of websites.
The Setup
After you’ve installed Python, you’ll need to import the library I’ll use here with pip. Open your terminal (Powershell on Windows, Terminal on Mac) and type:
Then create a text-file with the name app.py. This is your application file. You can use any ordinary text-editor to edit this file. I would recommend Atom, Sublime Text or Visual Code. Write into your file:
requests-html has the advantage over urllib and beautiful-soup since it’s way easier to use and combines the features of the two into one library.
Extracting Data
Now, that we’re all set up, we can go ahead and download data:
The sessionrequests websites like a normal web browser, and most importantly, it looks to the website like a browser as well. Let’s give our session a website to scrape:
This will download the so-called source of your page, in this case, my GitHub profile. Let’s download all the names of my repositories! Open the website in the browser of your choice, right-click on one of the list-items and select Inspect-Element.
You should now see the compiled page-source.
The list is in a <div> Element with the id “user-repositories-list” Let’s search for that.
This will return a list of all the repositories. A # is the html-marker for an id-tag. Now for every list, we want to find the name of the repository and its language to write in a file. First, we’ll prepare the data structure. The list should contain a header and then we want to append our data points.
Now let’s iterate over all elements in the list and find name and language.
elements is an array of all the info in each item on the list. For example, for the first item, it would look like this:
The first element (Nr. 0) is the name. The language is in third place so it has the id 2.
Saving your data
Now we have a 2-dimensional list of all the info we wanted. All we have to do is to write it in a file. CSV is an open table format, which can be opened with Excel, or similar programs. The CSV-Package implemented in Python can we used to read and write files easily:
You can now run your application in the terminal:
This should produce a CSV-file you can open with Excel.
You may notice that this isn’t 100% clean. Not all fields are selected correctly since this method is dependent on a specific format which is not always fulfilled. As an exercise try and fix this yourself.
You can refer to the documentation of
Requests-HTML has many more features, like asynchronous data collection, JavaScript support and automatic redirects. Certainly a great tool if you want to get further into web scraping.
If you have any further questions, feel free to comment below and I’ll try to get back to you.
Web Scraping с помощью python
Недавно заглянув на КиноПоиск, я обнаружила, что за долгие годы успела оставить более 1000 оценок и подумала, что было бы интересно поисследовать эти данные подробнее: менялись ли мои вкусы в кино с течением времени? есть ли годовая/недельная сезонность в активности? коррелируют ли мои оценки с рейтингом КиноПоиска, IMDb или кинокритиков?
Но прежде чем анализировать и строить красивые графики, нужно получить данные. К сожалению, многие сервисы (и КиноПоиск не исключение) не имеют публичного API, так что, приходится засучить рукава и парсить html-страницы. Именно о том, как скачать и распарсить web-cайт, я и хочу рассказать в этой статье.
В первую очередь статья предназначена для тех, кто всегда хотел разобраться с Web Scrapping, но не доходили руки или не знал с чего начать.
Off-topic: к слову, Новый Кинопоиск под капотом использует запросы, которые возвращают данные об оценках в виде JSON, так что, задача могла быть решена и другим путем.
Задача
- Этап 1: выгрузить и сохранить html-страницы
- Этап 2: распарсить html в удобный для дальнейшего анализа формат (csv, json, pandas dataframe etc.)
Инструменты
Регулярные выражения, конечно, нам пригодятся, но использовать только их, на мой взгляд, слишком хардкорный путь, и они немного не для этого. Были придуманы более удобные инструменты для разбора html, так что перейдем к ним. , lxml
Это две наиболее популярные библиотеки для парсинга html и выбор одной из них, скорее, обусловлен личными предпочтениями. Более того, эти библиотеки тесно переплелись: BeautifulSoup стал использовать lxml в качестве внутреннего парсера для ускорения, а в lxml был добавлен модуль soupparser. Подробнее про плюсы и минусы этих библиотек можно почитать в обсуждении. Для сравнения подходов я буду парсить данные с помощью BeautifulSoup и используя XPath селекторы в модуле lxml.html.
Это уже не просто библиотека, а целый open-source framework для получения данных с веб-страниц. В нем есть множество полезных функций: асинхронные запросы, возможность использовать XPath и CSS селекторы для обработки данных, удобная работа с кодировками и многое другое (подробнее можно почитать тут). Если бы моя задача была не разовой выгрузкой, а production процессом, то я бы выбрала его. В текущей постановке это overkill.
Загрузка данных
Первая попытка
Приступим к выгрузке данных. Для начала, попробуем просто получить страницу по url и сохранить в локальный файл.
Открываем полученный файл и видим, что все не так просто: сайт распознал в нас робота и не спешит показывать данные.
Разберемся, как работает браузер
Однако, у браузера отлично получается получать информацию с сайта. Посмотрим, как именно он отправляет запрос. Для этого воспользуемся панелью «Сеть» в «Инструментах разработчика» в браузере (я использую для этого Firebug), обычно нужный нам запрос — самый продолжительный.
Как мы видим, браузер также передает в headers UserAgent, cookie и еще ряд параметров. Для начала попробуем просто передать в header корректный UserAgent.
На этот раз все получилось, теперь нам отдаются нужные данные. Стоит отметить, что иногда сайт также проверяет корректность cookie, в таком случае помогут sessions в библиотеке Requests.
Скачаем все оценки
Теперь мы умеем сохранять одну страницу с оценками. Но обычно у пользователя достаточно много оценок и нужно проитерироваться по всем страницам. Интересующий нас номер страницы легко передать непосредственно в url. Остается только вопрос: «Как понять сколько всего страниц с оценками?» Я решила эту проблему следующим образом: если указать слишком большой номер страницы, то нам вернется вот такая страница без таблицы с фильмами. Таким образом мы можем итерироваться по страницам до тех, пор пока находится блок с оценками фильмов ( <div > ).
Парсинг
Немного про XPath
XPath — это язык запросов к xml и xhtml документов. Мы будем использовать XPath селекторы при работе с библиотекой lxml (документация). Рассмотрим небольшой пример работы с XPath
Подробнее про синтаксис XPath также можно почитать на W3Schools.
Вернемся к нашей задаче
Теперь перейдем непосредственно к получению данных из html. Проще всего понять как устроена html-страница используя функцию «Инспектировать элемент» в браузере. В данном случае все довольно просто: вся таблица с оценками заключена в теге <div > . Выделим эту ноду:
Каждый фильм представлен как <div > или <div > . Рассмотрим, как вытащить русское название фильма и ссылку на страницу фильма (также узнаем, как получить текст и значение атрибута).
Еще небольшой хинт для debug’a: для того, чтобы посмотреть, что внутри выбранной ноды в BeautifulSoup можно просто распечатать ее, а в lxml воспользоваться функцией tostring() модуля etree.
Резюме
В результате, мы научились парсить web-сайты, познакомились с библиотеками Requests, BeautifulSoup и lxml, а также получили пригодные для дальнейшего анализа данные о просмотренных фильмах на КиноПоиске.
Полный код проекта можно найти на github’e.
How to read html from a url in python 3
I looked at previous similar questions and got only more confused.
In python 3.4, I want to read an html page as a string, given the url.
In perl I do this with LWP::Simple, using get().
A matplotlib 1.3.1 example says: import urllib; u1=urllib.urlretrieve(url) . python3 can’t find urlretrieve .
I tried u1 = urllib.request.urlopen(url) , which appears to get an HTTPResponse object, but I can’t print it or get a length on it or index it.
u1.body doesn’t exist. I can’t find a description of the HTTPResponse in python3.
Is there an attribute in the HTTPResponse object which will give me the raw bytes of the html page?
(Irrelevant stuff from other questions include urllib2 , which doesn’t exist in my python, csv parsers, etc.)
Edit:
I found something in a prior question which partially (mostly) does the job:
I say ‘partially’ because I don’t want to read separate lines, but just one big string.
I could just concatenate the lines, but every line printed has a character ‘b’ prepended to it.
Where does that come from?
Again, I suppose I could delete the first character before concatenating, but that does get to be a kloodge.
6 Answers 6
Note that Python3 does not read the html code as a string but as a bytearray , so you need to convert it to one with decode .
Try the ‘requests’ module, it’s much simpler.
urllib.request.urlopen(url).read() should return you the raw HTML page as a string.
This will work similar to urllib.urlopen .
Reading an html page with urllib is fairly simple to do. Since you want to read it as a single string I will show you.
Import urllib.request:
Prepare our request
Always use a «try/except» when requesting a web page as things can easily go wrong. urlopen() requests the page.
Type is a great function that will tell us what ‘type’ a variable is. Here, response is a http.response object.
The read function for our response object will store the html as bytes to our variable. Again type() will verify this.
Now we use the decode function for our bytes variable to get a single string.
If you do want to split up this string into separate lines, you can do so with the split() function. In this form we can easily iterate through to print out the entire page or do any other processing.
Hopefully this provides a little more detailed of an answer. Python documentation and tutorials are great, I would use that as a reference because it will answer most questions you might have.