Написать программу для проверки наличия комментария в заголовке файлов с расширением c js и py

Обновлено: 08.07.2024

Я пытаюсь разработать простой веб-скребок. Я хочу извлечь текст без кода HTML. На самом деле я достиг этой цели, но я видел, что на некоторых страницах, где загружен JavaScript, я не добился хороших результатов.

Например, если какой-то код JavaScript добавляет текст, я не вижу его, потому что когда я звоню

Я получаю оригинальный текст без добавленного (потому что JavaScript выполняется в клиенте).

Итак, я ищу несколько идей для решения этой проблемы.

Похоже, вам может понадобиться что-то тяжелее, попробуйте Selenium или Watir.

РЕДАКТИРОВАТЬ 30 / Dec / 2017: этот ответ появляется в топ-результатах поиска Google, поэтому я решил обновить его. Старый ответ еще в конце.

Dryscape больше не поддерживается, и разработчики библиотеки Dryscape рекомендуют использовать только Python 2. Я обнаружил, что использование библиотеки Python Selenium с Phantom JS в качестве веб-драйвера достаточно быстрое и простое для выполнения работы.

После установки Phantom JS убедитесь, что phantomjs двоичный файл доступен по текущему пути:

Чтобы привести пример, я создал образец страницы со следующим HTML-кодом. ( ссылка ):

без JavaScript это говорит: No javascript support и с Javascript: Yay! Supports javascript

Вы также можете использовать библиотеку Python dryscrape для очистки сайтов, управляемых javascript.

Какие-нибудь альтернативы для тех из нас, кто программирует в Windows? @Expenzor Я работаю над окнами. PhantomJS работает отлично. Стоит отметить, что PhantomJS больше не выпускается и больше не находится в активной разработке в свете Chrome, который теперь поддерживает безголовый. Рекомендуется использовать безголовый Chrome / Firefox.

Мы не получаем правильных результатов, потому что любой контент, сгенерированный javascript, должен отображаться в DOM. Когда мы выбираем HTML-страницу, мы получаем исходную, не измененную Javascript, DOM.

Поэтому нам нужно визуализировать содержимое javascript перед сканированием страницы.

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

Решение 1: Это очень хороший учебник о том, как использовать Scrapy для сканирования контента, созданного на JavaScript, и мы собираемся следовать этому.

Что нам понадобится:

Докер установлен на нашей машине. До этого момента это преимущество перед другими решениями, поскольку оно использует независимую от ОС платформу.

Установите Splash, следуя инструкциям для нашей соответствующей ОС.
Цитирование из всплеск документации:

По сути, мы будем использовать Splash для визуализации сгенерированного Javascript контента.

Запустите сервер заставки sudo docker run -p 8050:8050 scrapinghub/splash .

Установите плагин scrapy-splash : pip install scrapy-splash

Предполагая, что у нас уже есть проект Scrapy (если нет, давайте создадим его ), мы будем следовать руководству и обновим settings.py :

Затем перейдите в свой проект Scrapy settings.py и установите эти промежуточные программы:

URL-адрес сервера Splash (если вы используете Win или OSX, это должен быть URL-адрес докера: как получить IP-адрес контейнера Docker от хоста? ):

И, наконец, вам нужно установить эти значения тоже:

Наконец, мы можем использовать SplashRequest :

У обычного паука у вас есть объекты Request, которые вы можете использовать для открытия URL. Если страница, которую вы хотите открыть, содержит данные, сгенерированные JS, вы должны использовать SplashRequest (или SplashFormRequest) для отображения страницы. Вот простой пример:

SplashRequest отображает URL как html и возвращает ответ, который вы можете использовать в методе обратного вызова (синтаксический анализ).

Решение 2: Давайте назовем этот эксперимент в настоящий момент (май 2018) .
Это решение только для версии Python 3.6 (на данный момент).

Знаете ли вы модуль запросов (ну, кто не знает)?
Теперь у него есть маленький брат, просматривающий веб: запросы-HTML :

Эта библиотека предназначена для того, чтобы сделать анализ HTML (например, просмотр веб-страниц) максимально простым и интуитивно понятным.

Установить запросы-HTML: pipenv install requests-html

Сделайте запрос на URL страницы:

Отобразите ответ, чтобы получить сгенерированные Javascript биты:

Наконец, модуль предлагает возможности очистки .
Кроме того, мы можем попробовать хорошо документированный способ использования BeautifulSoup с r.html объектом, который мы только что визуализировали.

Можете ли вы рассказать о том, как получить полный HTML-контент с загруженными битами JS после вызова .render ()? Я застрял после этого момента. Я не вижу всех фреймов, которые обычно вставляются на страницу из JavaScript в r.html.html объекте. @ anon58192932 Так как на данный момент это экспериментальное решение, и я не знаю, что именно вы пытаетесь достичь в результате, я не могу ничего предложить . Вы можете создать новый вопрос здесь на SO, если у вас нет разработал решение еще Я получил эту ошибку: RuntimeError: Невозможно использовать HTMLSession в существующем цикле событий. Вместо этого используйте AsyncHTMLSession.

Может быть, селен может сделать это.

Selenium действительно тяжел для такого рода вещей, это было бы излишне медленно и требует головы браузера, если вы не используете PhantomJS, но это будет работать. @JoshuaHedges Вы можете запустить другие более стандартные браузеры в режиме без головы.

Если вы когда-либо использовали Requests модуль для Python ранее, я недавно обнаружил, что разработчик создал новый модуль, Requests-HTML который теперь также имеет возможность визуализации JavaScript.

По сути, после правильной установки Requests-HTML модуля в следующем примере, показанном по вышеуказанной ссылке , показано, как можно использовать этот модуль для очистки веб-сайта и рендеринга JavaScript, содержащегося на веб-сайте:

Я недавно узнал об этом из видео на YouTube. Кликните сюда! смотреть видео на YouTube, которое демонстрирует, как работает модуль.

Следует отметить, что этот модуль поддерживает только Python 3.6. @HuckIt Извинения Я не знаком с этой ошибкой, однако, похоже, что ошибка, веб-сайт, на который вы пытались попасть, мог иметь проблему, связанную с сертификацией SSL. Извините, это не решение, но я бы порекомендовал вам задать новый вопрос здесь, в переполнении стека (если он еще не задавался), и, возможно, предоставить более подробную информацию, такую ​​как URL-адрес веб-сайта, который вы использовали, и ваш код. Кажется, использовать хром под капотом. Работает отлично для меня, хотя

Это также кажется хорошим решением, взятым из отличного поста в блоге.

Похоже, к данным, которые вы действительно ищете, можно получить доступ через вторичный URL, который вызывается каким-то javascript на основной странице.

@ Kris На всякий случай, если кто-то наткнется на это и захочет попробовать его вместо чего-то такого тяжелого, как селен, вот короткий пример. Это откроет страницу детали детали для шестигранной гайки на сайте МакМастер-Карр. Их веб-сайт в основном выбирается с использованием Javascript и содержит очень мало информации о нативных страницах. Если вы откроете инструменты разработчика своего браузера, перейдете на вкладку Сеть и обновите страницу, вы сможете увидеть все запросы, сделанные этой страницей, и найти соответствующие данные (в данном случае html деталей). Это другой URL-адрес, который можно найти на вкладке «Сеть» Firefox devtool, которая, если она используется, содержит html для большей части информации о деталях и предоставляет некоторые параметры, необходимые для простой навигации к другой информации о деталях для упрощения очистки. Этот конкретный пример не особенно полезен, поскольку цена генерируется другой функцией Javascript, но он должен послужить хорошим введением для тех, кто хочет следовать совету Стивена.

Селен лучше всего подходит для очистки содержимого JS и Ajax.

Затем загрузите веб-драйвер Chrome.

Вы также можете выполнить JavaScript с помощью веб-драйвера.

или сохранить значение в переменной

или вы можете просто использовать driver.title собственность

Лично я предпочитаю использовать скрап и селен, а также докеризацию в отдельных контейнерах. Таким образом, вы можете установить как с минимальными хлопотами, так и сканировать современные веб-сайты, которые почти все содержат JavaScript в той или иной форме. Вот пример:

Используйте, scrapy startproject чтобы создать свой скребок и написать свой паук, скелет может быть таким простым:

Настоящая магия происходит в middlewares.py. Перезаписать два метода в промежуточном программном обеспечении загрузчика, __init__ и process_request , следующим образом:

Не забудьте включить эту промежуточную программу, раскомментировав следующие строки в файле settings.py:

Далее для докеризации. Создайте свой Dockerfile из облегченного образа (я использую Python Alpine здесь), скопируйте в него каталог вашего проекта, установите требования:

И, наконец, свести все это в docker-compose.yaml :

Беги docker-compose up -d . Если вы делаете это в первый раз, потребуется некоторое время, чтобы он извлек последнюю версию селен / автономный хром, а также построил ваш скребковый образ.

Как только это будет сделано, вы можете проверить, что ваши контейнеры работают, docker ps а также убедиться, что имя контейнера селена совпадает с именем переменной среды, которую мы передали нашему контейнеру скребка (здесь это было SELENIUM_LOCATION=samplecrawler_selenium_1 ).

Введите свой контейнер скребка с docker exec -ti YOUR_CONTAINER_NAME sh помощью команды для меня docker exec -ti samplecrawler_my_scraper_1 sh , перейдите в правильный каталог и запустите свой скребок с помощью scrapy crawl my_spider .

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

2,545 21 21 золотой знак 58 58 серебряных знаков 103 103 бронзовых знака на сервере можно посмотреть Content-Length и не загружать, если выходит за лимит

В html5 была добавлена поддержка File API – с помощью которого можно получить имя, размер и MIME тип выбранного файла ещё до загрузки его на сервер.

У объекта DOM <input type="file" ..> , после выбора пользователем файла, можно считать свойство files – объект FileList – содержащим объекты File .

У File есть свойства size , name и type . В нашем случае выбирается всего один файл, сразу его и берём:

30.4k 3 3 золотых знака 44 44 серебряных знака 81 81 бронзовый знак

У элемента <input> есть параметр value . В этом параметре находится полное название файла, включая расширение:

Размер файла без предзагрузки через флеш, через FileReader @Grundy

Не надо проверять расширение файла, по-хорошему надо проверять его тип (проверятся так же как и размер, только не size , а type ).

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


55.2k 7 7 золотых знаков 63 63 серебряных знака 134 134 бронзовых знака Хм и как это проверять, если непонятно от чего зависит. media-type - это стандартизованная вещь, и про популярные форматы все браузеры знают Не надо проверять расширение файла, Обычно - по расширению. - так какая разница?

В новой спецификации можно полностью контент файла на js получить, но работать будет не везде, а только где FileReader есть:

Однажды пришлось считать хэш от содержимого файла на клиенте, делал примерно так:

Вот это sBase64Data содержимое файла в base64. Тут можно и размер посчитать.

А экстеншен, понятно только по имени узнать можно, иначе никак:

UPD

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

Мнение о том, что JavaScript не умеет взаимодействовать с файловой системой, является не совсем верным. Скорее, речь идет о том, что это взаимодействие существенно ограничено по сравнению с серверными языками программирования, такими как Node.js или PHP. Тем не менее, JavaScript умеет как получать (принимать), так и создавать некоторые типы файлов и успешно обрабатывать их нативными средствами.

В этой статье мы создадим три небольших проекта:

  • Реализуем получение и обработку изображений, аудио, видео и текста в формате txt и pdf
  • Создадим генератор JSON-файлов
  • Напишем две программы: одна будет формировать вопросы (в формате JSON), а другая использовать их для создания теста

Получаем и обрабатываем файлы

Для начала создадим директорию, в которой будут храниться наши проекты. Назовем ее «Work-With-Files-in-JavaScript» или как Вам будет угодно.

В этой директории создадим папку для первого проекта. Назовем ее «File-Reader».

Создаем в ней файл «index.html» следующего содержания:


Здесь мы имеем контейнер-файлоприемник и инпут с типом «file» (для получения файла; мы будем работать с одиночными файлами; для получения нескольких файлов инпуту следует добавить атрибут «multiple»), который будет спрятан под контейнером.

Стили можно подключить отдельным файлом или в теге «style» внутри head:


Можете сделать дизайн по своему вкусу.

Не забываем подключить скрипт либо в head с атрибутом «defer» (нам нужно дождаться отрисовки (рендеринга) DOM; можно, конечно, сделать это в скрипте через обработку события «load» или «DOMContentLoaded» объекта «window», но defer намного короче), либо перед закрывающим тегом «body» (тогда не нужен ни атрибут, ни обработчик). Лично я предпочитаю первый вариант.

Откроем index.html в браузере:


Прежде чем переходить к написанию скрипта, следует подготовить файлы для приложения: нам потребуется изображение, аудио, видео, текст в формате txt, pdf и любом другом, например, doc. Можете использовать мою коллекцию или собрать свою.

Нам часто придется обращаться к объектам «document» и «document.body», а также несколько раз выводить результаты в консоль, поэтому предлагаю обернуть наш код в такое IIFE (это не обязательно):


Первым делом объявляем переменные для файлоприемника, инпута и файла (последний не инициализируем, поскольку его значение зависит от способа передачи — через клик по инпуту или бросание (drop) в файлоприемник):

Отключаем обработку событий «dragover» и «drop» браузером:


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

Обрабатываем бросание файла в файлоприемник:


Мы только что реализовали простейший механизм «dran'n'drop».

Обрабатываем клик по файлоприемнику (делегируем клик инпуту):


Приступаем к обработке файла:


Удаляем файлоприемник и инпут:


Способ обработки файла зависит от его типа:


Мы не будем работать с html, css и js-файлами, поэтому запрещаем их обработку:


Мы также не будем работать с MS-файлами (имеющими MIME-тип «application/msword», «application/vnd.ms-excel» и т.д.), поскольку их невозможно обработать нативными средствами. Все способы обработки таких файлов, предлагаемые на StackOverflow и других ресурсах, сводятся либо к конвертации в другие форматы с помощью различных библиотек, либо к использованию viewer'ов от Google и Microsoft, которые не хотят работать с файловой системой и localhost. Вместе с тем, тип pdf-файлов также начинается с «application», поэтому такие файлы мы будем обрабатывать отдельно:


Для остальных файлов получаем их «групповой» тип:


Посредством switch..case определяем конкретную функцию обработки файла:

По мере увеличения размера программ весь код уже не помещается в нескольких файлах, записывать каждый раз предварительные объявления для функций, которые мы хотим использовать, но которые находятся в других файлах, становится всё утомительнее и утомительнее. Хорошо было бы, если бы все предварительные объявления находились в одном месте, не так ли?

Заголовочные файлы из Стандартной библиотеки C++

Рассмотрим следующую программу:

Результат выполнения программы:

Как правило, в заголовочных файлах записываются только объявления, без определений. Следовательно, если cout только объявлен в заголовочном файле iostream, то где же он определяется? Ответ: в Стандартной библиотеке С++, которая автоматически подключается к вашему проекту на этапе линкинга.


Пишем свои собственные заголовочные файлы

Теперь давайте вернемся к примеру, который мы обсуждали на предыдущем уроке. У нас было два файла: add.cpp и main.cpp.

int add ( int x , int y ) ; // предварительное объявление с использованием прототипа функции std :: cout << "The sum of 3 and 4 is " << add ( 3 , 4 ) << std :: endl ;

Примечание: Если вы создаете все файлы заново, то не забудьте добавить add.cpp в свой проект, чтобы он был подключен к компиляции.

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

Написать свой собственный заголовочный файл не так уж и сложно. Заголовочные файлы состоят из двух частей:

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

Содержимое заголовочного файла — набор объявлений.

Все ваши заголовочные файлы (которые вы написали самостоятельно) должны иметь расширение .h .

// Начнем с директив препроцессора. ADD_H – это произвольное уникальное имя (обычно используется имя заголовочного файла) int add ( int x , int y ) ; // прототип функции add() (не забывайте точку с запятой в конце!)

Чтобы использовать этот файл в main.cpp, вам сначала нужно будет подключить его к проекту.

main.cpp, в котором мы подключаем add.h:

std :: cout << "The sum of 3 and 4 is " << add ( 3 , 4 ) << std :: endl ;

add.cpp остается без изменений:

Если вы получили ошибку от линкера, что функция аdd() не определена, то убедитесь, что вы корректно подключили add.cpp к вашему проекту (и к компиляции тоже)!

Стоит отметить, что одни заголовочные файлы могут подключать другие заголовочные файлы. Тем не менее, так делать не рекомендуется.

Почему iostream пишется без окончания .h?

Когда C++ только создавался, все файлы библиотеки Runtime имели окончание .h. Оригинальные версии cout и cin объявлены в iostream.h. При стандартизации языка С++ комитетом ANSI, решили перенести все функции из библиотеки Runtime в пространствo имен std, чтобы предотвратить возможность возникновения конфликтов имен с пользовательскими идентификаторами (что, между прочим, является хорошей идеей). Тем не менее, возникла проблема: если все функции переместить в пространство имен std, то старые программы переставали работать!

Когда вы подключаете заголовочный файл из Стандартной библиотеки C++, убедитесь, что вы используете версию без .h (если она существует). В противном случае, вы будете использовать устаревшую версию заголовочного файла, который уже больше не поддерживается.

Кроме того, многие библиотеки, унаследованные от языка Cи, которые до сих пор используются в C++, также были продублированы с добавлением префикса c (например, stdlib.h стал cstdlib). Функционал этих библиотек также перенесли в пространство имен std, чтобы избежать возможность возникновения конфликтов имен с пользовательскими идентификаторами.

Можно ли записывать определения в заголовочных файлах?

Язык C++ не будет жаловаться, если вы это сделаете, но так делать не принято.

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

Советы

Вот несколько советов по написанию собственных заголовочных файлов:

Всегда используйте директивы препроцессора.

Не определяйте переменные в заголовочных файлах, если это не константы. Заголовочные файлы следует использовать только для объявлений.

Читайте также: