2016-12-12 2 views
1

Я использую Scrapy для сканирования и очистки данных с веб-сайтов, которые в основном состоят из html-страниц и файлов PDF (я изменил IGNORED_EXTENSIONS, чтобы разрешить очистку pdf-файлов).Извлечение информации из элементов привязки, приводящих к файлам PDF

Мне нужно извлечь текст, который захватывается между <a> тегами:

<a href='some_document.pdf'>I need this text</a> 

Очевидно, что я не могу сделать response.text или response.css, так как есть только байты для чтения (вы получаете AttributeError).

Одна вещь, которая пришла мне на ум, заключалась в обходе страницы, извлечении всех ссылок с этой страницы и сохранении их в текстовом файле. Это сработало, за исключением того, что у меня появилось много дублирующих ссылок, ссылок, которые были сломаны (думаю, 403, 404, 500) или много ссылок, на которые меня не волновало. Я думаю, что должен быть лучший способ!

При чтении документации по Scrapy я наткнулся на документ для LxmlLinkExtractor. Там в «Конструктор», он имеет 2 интересные поля:

  • метки (ул или список) - тег или список тегов, которые следует учитывать при извлечении ссылки. По умолчанию ('a', 'area').
  • attrs (list) - атрибут или список атрибутов, которые следует учитывать при поиске ссылок для извлечения (только для тех тегов, которые указаны в параметре тегов). По умолчанию («HREF»,)

И это заставило меня задуматься, возможно ли, чтобы захватить значения атрибутов <a> элемента перед сканированием его. Я прав? И если да, как я могу захватить текст между тегами?

Исходный код:

class ArchiveSpider(CrawlSpider): 

...some code... 

rules = [ 
     Rule(LinkExtractor(allow=[re.compile('pdf', re.IGNORECASE)]), 
          callback='parse_pdf', 
          follow=True), 
     Rule(LinkExtractor(), callback='parse_item', follow=True) 
    ] 

    def parse_pdf(self, response): 
     yield dict(url=response.url) 

    def parse_item(self, response): 
     if re.search(re.compile('pdf', re.IGNORECASE, response.headers.get('Content-Type').decode('utf-8')): 
      parse_pdf(self, response) 
     title = response.css('title::text').extract()[0].strip() if response.css('title::text') else '' 
     yield dict(title=title, url=response.url) 

ответ

0

Я не уверен, что я правильно вас понимаю, но не могли бы вы сделать что-то вроде этого:

text = response.xpath('//a/text()').extract() 

Вы должны указать желаемое <a> -элементы в xpath, text() выбирает текст между тегами.

Смежные вопросы