Scrapy CrawlSpider обрабатывает ссылки на основе функций Javascript

#python #scrapy

#python #scrapy

Вопрос:

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

 <a href="javascript:fn_egov_view('2106022');" title="This is the title.">This is the title.
 

Которые создают ссылку вида:

 https://ombudsman.abc.de/eng/rli/lgs/na.do?mode=viewamp;blNo=2106022
 

Таким образом, их, казалось бы, можно легко обойти, извлекая номер из ссылки, а затем добавляя его к базовому URL-адресу, который никогда не меняется.

Мой код для этого выглядит так

 class MyCrawler(CrawlSpider):
    name = 'ombudsman'
    allowed_domains = ['ombudsman.abc.de']
    start_urls = ['https://ombudsman.abc.de/eng/rli/lgs/na.do?mode=list']

    rules = (
        Rule(LinkExtractor(restrict_xpaths='//*[@id="legSchVO"]/div/div[3]/table/tbody/tr[1]/td[3]/a'), follow=True, callback='parse_item', process_links='process_links'),
    )

    def process_links(self, links):
        for link in links:
            url_number = re.findall(r'd ', link.url)
            link.url = "https://ombudsman.abc.de/eng/rli/lgs/na.do?mode=viewamp;blNo="   url_number
            yield links

    def parse_item(self, response):
        l = ItemLoader(item=ReleasesItem(), response=response)
        l.default_output_processor = MapCompose(lambda v: v.strip(), replace_escape_chars)

        l.add_value('rel_org', 'Ombudsman')
        l.add_xpath('rel_title', '//*[@id="container"]/div[2]/div[2]/div[1]/dl[1]/dd/text()')
        l.add_xpath('rel_summary', '//*[@id="container"]/div[2]/div[2]/div[1]/div/table[1]/tbody/tr/td')
        l.add_xpath('rel_scraped_date', '//*[@id="container"]/div[2]/div[2]/div[1]/dl[3]/dd[1]/text()')
        l.add_value('rel_url', response.url)
        yield l.load_item()
 

К сожалению, кажется, что LinkExtractor в правиле вообще не собирается href="" часть ссылки и, следовательно, просто отправляет пустой список process_links . Затем искатель останавливается после возврата только первой страницы.

Есть ли способ вернуть LinkExtractor href в качестве URL-адреса как есть? Или, если нет, какие-либо рекомендации о том, как это сделать?

Комментарии:

1. может быть, сначала проверьте, что он получает href или во всех HTML . Возможно, это дает вам другой HTML / href, когда вы используете его без JavaScript.

2. Нет разницы с отключенным javascript. Ссылки просто не работают вообще.

3. Я думаю, что вижу ошибку — вы используете yield links , но это может понадобиться yield link.url . Вы можете добавить print() функции, чтобы увидеть, что у вас есть в переменных.

4. Я пробовал функции печати. process_links получает пустой список.

5. и вы использовали print() для проверки других значений в функции? Возможно, таким образом вы поймете, почему он отправляет пустой список. Это называется «отладкой печати».

Ответ №1:

url_number = re.findall(r'd ', link.url) возвращает список, поэтому используйте url_number[0] вместо url_number , и yield link вместо yield links

Нравится:

     def process_links(self, links):
        for link in links:
            url_number = re.findall(r'd ', link.url)
            if len(url_number)>0: 
                link.url = "https://ombudsman.abc.de/eng/rli/lgs/na.do?mode=viewamp;blNo="   url_number[0]
            yield link
 

Комментарии:

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

2. вы проверили xpaths?

3. Да, я думаю, что LinkExtractor выполняет какую-то предварительную обработку, чтобы определить, что является ссылкой, а что нет, что мешает ему принимать href="javascript:fn_egov_view('2106022');" ссылки типа как приемлемые. Он не находит ссылок, поэтому ничего не передает.