В этом разделе мы используем Toutiao в качестве примера, чтобы попытаться собрать данные веб-страницы, анализируя запросы Ajax. На этот раз целью является уличная фотография Toutiao.После завершения захвата каждая группа изображений будет загружена в локальную папку и сохранена.
1. Подготовка
Прежде чем начать этот раздел, убедитесь, что библиотека запросов установлена. Если он не установлен, вы можете проверить это самостоятельно.
2. Анализ сканирования
Перед ползанием, сначала проанализируйте логику ползания. Откройте домашнюю страницу Toutiao http://www.toutiao.com/, как показано на рисунке ниже.
В правом верхнем углу есть поисковый вход, здесь мы пытаемся захватить уличную фотографию, поэтому введите слово «Уличная фотография» для поиска, и результат, как показано ниже.
Затем откройте инструменты разработчика и просмотрите все сетевые запросы. Сначала откройте первый сетевой запрос, URL этого запроса — текущая ссылка http://www.toutiao.com/search/?keyword=Street Shooting, откройте вкладку «Предварительный просмотр», чтобы просмотреть текст ответа. Если контент на странице отображается в соответствии с результатом, полученным по первому запросу, то исходный код первого запроса должен содержать текст в результате страницы. Чтобы проверить, мы можем попытаться выполнить поиск по названию результата поиска, например по слову «прохожий», как показано на следующем рисунке.
Мы обнаружили, что эти два слова не были включены в исходный код веб-страницы, а количество поисковых совпадений равно 0. Поэтому можно предварительно судить, что это содержимое загружается Ajax, а затем рендерится JavaScript. Далее мы можем переключиться на вкладку фильтрации XHR и посмотреть, есть ли какие-либо Ajax-запросы.
Неудивительно, что здесь есть довольно регулярный запрос Ajax, и посмотрите, содержит ли его результат соответствующие данные со страницы.
нажмитеdata
Разверните поле и обнаружите, что здесь много фрагментов данных. Нажмите на первый элемент, чтобы развернуть, вы можете обнаружить, что естьtitle
поле, а его значение точно совпадает с заголовком первой части данных на странице. Снова проверьте другие данные, и они находятся во взаимно однозначном соответствии, как показано на следующем рисунке.
Это определяет, что данные действительно загружены AJAX.
Наша цель - запечатлеть в нем красивые снимки, здесь группа снимков соответствует переднемуdata
Часть данных в поле. Для каждых данных есть еще одинimage_detail
поле в виде списка, содержащего список всех изображений групповой диаграммы, как показано на следующем рисунке.
Поэтому нам нужно только поставитьurl
Просто извлеките поля и загрузите их. Для каждой группы изображений создается папка, и имя папки является заголовком группового изображения.
Затем вы можете напрямую использовать Python для моделирования запроса Ajax, а затем извлечь соответствующие красивые ссылки на изображения и загрузить их. Но перед этим нам также необходимо проанализировать закон URL.
Вернитесь на вкладку «Заголовки» и просмотрите URL-адрес запроса и информацию о заголовках, как показано на рисунке ниже.
Как видите, это GET-запрос, и параметры URL-адреса запросаoffset
,format
,keyword
,autoload
,count
иcur_tab
. Нам нужно выяснить закон этих параметров, потому что это легко строится программой.
Затем вы можете провести по странице, чтобы загрузить больше новых результатов. При загрузке можно обнаружить, что в Сети много Ajax-запросов, как показано на следующем рисунке.
Посмотрите здесь параметры последующих ссылок и обнаружите, что измененные параметры толькоoffset
, остальные параметры не изменились, а второй запросoffset
Значение 20, в третий раз 40, а в четвертый раз 60, так что вы можете найти закон, этоoffset
Значение представляет собой смещение, которое, в свою очередь, можно вывестиcount
Параметр представляет собой количество фрагментов данных, которые необходимо получить за один раз. Поэтому мы можем использоватьoffset
Параметры для управления подкачкой данных. Таким образом, мы можем получать данные пакетами через интерфейс, затем анализировать данные и загружать изображения.
3. Практические занятия
Мы только что разобрали логику Ajax-запроса, воспользуемся программой для загрузки красивой картинки.
Сначала реализуем методget_page()
для загрузки результатов одного запроса Ajax. Меняется только параметрoffset
, поэтому мы передаем его как параметр, реализованный следующим образом:
import requests
from urllib.parse import urlencode
def get_page(offset):
params = {
'offset': offset,
'format': 'json',
'keyword': '街拍',
'autoload': 'true',
'count': '20',
'cur_tab': '1',
}
url = 'http://www.toutiao.com/search_content/?' + urlencode(params)
try:
response = requests.get(url)
if response.status_code == 200:
return response.json()
except requests.ConnectionError:
return None
Здесь мы используемurlencode()
Метод строит параметр GET запроса, а затем запрашивает ссылку с запросами.Если код состояния возврата равен 200, вызовитеresponse
изjson()
Метод преобразует результат в формат JSON и возвращает его.
Затем реализуйте другой метод синтаксического анализа: извлекитеimage_detail
Для каждой ссылки на изображение в поле верните ссылку на изображение и заголовок, к которому принадлежит изображение.В это время можно построить генератор. Код реализации выглядит следующим образом:
def get_images(json):
if json.get('data'):
for item in json.get('data'):
title = item.get('title')
images = item.get('image_detail')
for image in images:
yield {
'image': image.get('url'),
'title': title
}
Далее реализуем метод сохранения изображенияsave_image()
,вitem
это фронтget_images()
Словарь, возвращаемый методом. В этом методе сначалаitem
изtitle
чтобы создать папку, затем запросите эту ссылку на изображение, получите двоичные данные изображения и запишите их в файл в двоичной форме. Имя изображения может использовать значение MD5 его содержимого, что позволяет удалять дубликаты. Соответствующий код выглядит следующим образом:
import os
from hashlib import md5
def save_image(item):
if not os.path.exists(item.get('title')):
os.mkdir(item.get('title'))
try:
response = requests.get(item.get('image'))
if response.status_code == 200:
file_path = '{0}/{1}.{2}'.format(item.get('title'), md5(response.content).hexdigest(), 'jpg')
if not os.path.exists(file_path):
with open(file_path, 'wb') as f:
f.write(response.content)
else:
print('Already Downloaded', file_path)
except requests.ConnectionError:
print('Failed to Save Image')
Наконец, просто создайтеoffset
массив, итерацияoffset
, извлеките ссылку на изображение и загрузите его:
from multiprocessing.pool import Pool
def main(offset):
json = get_page(offset)
for item in get_images(json):
print(item)
save_image(item)
GROUP_START = 1
GROUP_END = 20
if __name__ == '__main__':
pool = Pool()
groups = ([x * 20 for x in range(GROUP_START, GROUP_END + 1)])
pool.map(main, groups)
pool.close()
pool.join()
Начальные и окончательные страницы пейджинга определены здесь соответственноGROUP_START
иGROUP_END
, также использует многопоточный пул потоков, вызывая егоmap()
Метод реализует многопоточную загрузку.
На этом вся программа завершена.После запуска вы обнаружите, что фотографии улиц сохранены в папках, как показано на следующем рисунке.
Наконец, мы даем кодовый адрес этого раздела: https://github.com/Python3WebSpider/Jiepai.
В этом разделе мы понимаем процесс анализа Ajax, моделирование пейджинга Ajax и процесс загрузки изображений.
Содержание этого раздела необходимо усвоить, и мы будем использовать этот вид анализа и захвата много раз в реальном бою.
Этот ресурс был впервые опубликован в личном блоге Цуй Цинцай Цзин Ми:Практическое руководство по разработке веб-краулера на Python3 | Цзин Ми
Если вы хотите узнать больше информации о поисковых роботах, обратите внимание на мой личный публичный аккаунт WeChat: Coder of Attack.
WeChat.QQ.com/Day/5 Это радость VE Z…(автоматическое распознавание QR-кода)