Scrapy возвращают Base64 изображения Url после 10 изображений - PullRequest
0 голосов
/ 06 октября 2018

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

"data: image / gif; base64, R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== "

Вот мой код паука

import scrapy
class CoinmarketcapSpider(scrapy.Spider):
    name = 'coinmarketcap'
    allowed_domains = ['coinmarketcap.com']
    start_urls = ['https://coinmarketcap.com/2']
    def parse(self, response):
        cointable=response.css('table#currencies').xpath('//tbody/tr')
        for coins in cointable:
            name=coins.css('a.currency-name-container::text').extract_first().strip()
            logo=coins.css('img.logo-sprite::attr(src)').extract()
            symbol=coins.css('span.currency-symbol').xpath('.//a/text()').extract_first().strip()
            market_cap=coins.css('.market-cap').xpath('text()').extract_first().strip()
            yield {
                'Name':name,
                'image_urls':logo,
                'symbol':symbol,
                'market_cap':market_cap
            }
        print response

Вот выходной файл json, который имеет ImgLogo url

[{" coinName ":["Биткойн"], "symbol": ["BTC"], "imgLogo": ["https://s2.coinmarketcap.com/static/img/coins/16x16/1.png"]}, {" coinName ": [" Ethereum "]," symbol ": [" ETH "],"imgLogo ": [" https://s2.coinmarketcap.com/static/img/coins/16x16/1027.png"]}, {"coinName": ["XRP"], "symbol": ["XRP"], "imgLogo": ["https://s2.coinmarketcap.com/static/img/coins/16x16/52.png"]}, {" coinName ": ["Наличные биткойны"], "symbol": ["BCH"], "imgLogo": ["https://s2.coinmarketcap.com/static/img/coins/16x16/1831.png"]}, {" coinName ": [" EOS "]," symbol ": [" EOS "],"imgLogo ": [" https://s2.coinmarketcap.com/static/img/coins/16x16/1765.png"]}, {"coinName": ["Stellar"], "symbol": ["XLM"], "imgLogo": ["https://s2.coinmarketcap.com/static/img/coins/16x16/512.png"]}, {" coinName ": ["Litecoin"], "symbol": ["LTC"], "imgLogo": ["https://s2.coinmarketcap.com/static/img/coins/16x16/2.png"]}, {" coinName ": [" Tether "]," symbol ": [" USDT "]," imgLogo "": [" https://s2.coinmarketcap.com/static/img/coins/16x16/825.png"]}, {"coinName": ["Cardano"], "symbol": ["ADA"], "imgLogo": ["https://s2.coinmarketcap.com/static/img/coins/16x16/2010.png"]}, {" coinName ": [" Monero "]," symbol ": [" XMR "]," imgLogo ": [" https://s2.coinmarketcap.com/static/img/coins/16x16/328.png"]}, {"coinName": ["IOTA"], "symbol": ["MIOTA"], "imgLogo": ["data: image / gif; base64, R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw =="]]}, {"coinName": ["TRON"], "symbol" ["]," imgLogo ": [" data: image / gif; base64, R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw == "]}, {" coinName ": [" Dash "]," symbol ": [" DASH "]," imgLogo"data: image / gif; base64, R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw =="]}]

Вот мой код Items.py

import scrapy
class CmindexItem(scrapy.Item):
    # define the fields for your item here like:
     image_urls = scrapy.Field()

Вот мой код piplines.py, который загружает кодизображений и сохраните их в моем каталоге изображений

import scrapy
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem


class CmindexPipeline(ImagesPipeline):
    def get_media_requests(self, item, info):
        for image_url in item['image_urls']:
            yield scrapy.Request(image_url)

    def item_completed(self, results, item, info):
        image_paths = [x['path'] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Item contains no images")
        item['image_paths'] = image_paths
        return item

Вот мой код settings.py

BOT_NAME = 'cmindex'

SPIDER_MODULES = ['cmindex.spiders']
NEWSPIDER_MODULE = 'cmindex.spiders'
USER_AGENT = 'cmindex (+http://www.cmindex.com)'
# Obey robots.txt rules
ROBOTSTXT_OBEY = True
ITEM_PIPELINES = {'cmindex.pipelines.CmindexPipeline': 1}
IMAGES_STORE ='E:\WorkPlace\cmindex\cmindex\img'
DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
    'scrapy_fake_useragent.middleware.RandomUserAgentMiddleware': 400,
}

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

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Прежде всего, это соответствующий необработанный HTML, который вы получите из ответа.

Фрагмент HTML для монеты в первых 10 строках

10
</td>
<td class="no-wrap currency-name" data-sort="Tether">
<img src="https://s2.coinmarketcap.com/static/img/coins/16x16/825.png" class="logo-sprite" alt="Tether" height="16" width="16">

Фрагмент HTML длямонета после 10-й строки

11
</td>
<td class="no-wrap currency-name" data-sort="TRON">
<img data-src="https://s2.coinmarketcap.com/static/img/coins/16x16/1958.png" class="logo-sprite lazyload" alt="TRON" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" height="16" width="16">

В основном сервер отправляет два разных формата данных.Один для строки 1-10, а другой для строки> 10. Как и строки 1-10, получают атрибут src, но со строки 11-го вы получаете атрибут src как base64 и data-src.Но я вижу, что атрибут data-src, наконец, применяется к атрибуту src на стороне браузера.

Следующий вопрос должен заключаться в том, почему он это делает?

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

Таким образом, в основном строки 1-10 имеют окончательный HTML-код для рендеринга в браузере, но в строке 11-й и далее магия происходит со сценарием Java.Теперь java-скрипт минимизирован и сжат, но я предполагаю, что следующие фрагменты (использующие изображение для лучшего представления) переносят значение атрибута data-src в атрибут src.data-src definition Setting src value from data-src

Сказав все это, я думаю, что безопасный способ отказаться - это использовать

  1. Использовать значение атрибутаof data-src
  2. Если data-src недоступен, используйте атрибут src.

И это источник или html, который будет видеть лоскут.enter image description here

Также src для строки 11 и более с "data: image / gif; base64, R0lGODlhAQABAAAAACH5BAEKAAAALAAAAAABAAEAAAICTAEAOw ==" является своего рода размещенным изображением держателя, я думаю, все онитакие же, и кажется, 1x1 пикселей.

0 голосов
/ 09 ноября 2018

Удалите следующие файлы из вашего settings.py

USER_AGENT = 'cmindex (+http://www.cmindex.com)'
DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
    'scrapy_fake_useragent.middleware.RandomUserAgentMiddleware': 400,
}

, а также отмените подписку Robotstxt

ROBOTSTXT_OBEY = False

И, пожалуйста, внесите следующие изменения в ваш файл паука.После просмотра источника coinmarketcap я обнаружил, что после 10 строк Src Image является бинарным. Так просто, тогда получите Data-src Image вместо src.

import scrapy
class CoinmarketcapSpider(scrapy.Spider):
name = 'coinmarketcap'
allowed_domains = ['coinmarketcap.com']
start_urls = ['https://coinmarketcap.com/']
def parse(self, response):

    cointable=response.css('table#currencies').xpath('//tbody/tr')
    for coins in cointable:
        name=coins.css('a.currency-name-container::text').extract_first().strip()
        logoData = coins.css('img.logo-sprite::attr(data-src)').extract()
        logoSrc=coins.css('img.logo-sprite::attr(src)').extract()
        if(logoData==[]):
            logo=logoSrc
        else:
            logo=logoData



        symbol=coins.css('span.currency-symbol').xpath('.//a/text()').extract_first().strip()
        market_cap=coins.css('.market-cap').xpath('text()').extract_first().strip()
        yield {
            'Name':name,
            'image_urls':logo,
            'symbol':symbol,
            'market_cap':market_cap,
        }
    print(response)
0 голосов
/ 07 октября 2018

data:image/gif;base64,R0l... - это полное изображение, закодированное в base64.

Ознакомьтесь с документацией mozillas по data-uris :

URL-адреса данных, URL-адреса с префиксом data: схема, позволяющая создателям контента вставлять небольшие файлы, встроенные вдокументы.

и

URL-адреса данных состоят из четырех частей: префикс (data :), тип MIME, указывающий тип данных, необязательный токен base64, еслинетекстовые, а сами данные:

data:[<mediatype>][;base64],<data>

В вашем случае медиатип: image/gif, закодирован в base64, а ваше фактическое изображение R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

Вы можете расшифровать его с помощью пакета base64 python:

with open('foo.gif', 'wb') as f:
    f.write(base64.b64decode("R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...