问题,而试图爬行的链接内访问的链接与刮?

2024-06-28 20:35:42 发布

您现在位置:Python中文网/ 问答频道 /正文

为了学习scrapy,我尝试从start_urls列表中抓取一些内部url。问题是不是所有来自start_urls的元素都有内部的urls(这里我想返回NaN)。因此,如何返回以下2列数据帧(**)

visited_link, extracted_link
https://www.example1.com, NaN
https://www.example2.com, NaN
https://www.example3.com, https://www.extracted-link3.com

到目前为止,我试着:

在:

# -*- coding: utf-8 -*-


class ToySpider(scrapy.Spider):
    name = "toy_example"

    allowed_domains = ["www.example.com"]

    start_urls = ['https:example1.com',
                  'https:example2.com',
                  'https:example3.com']


    def parse(self, response):
        links = response.xpath(".//*[@id='object']//tbody//tr//td//span//a")

        lis_ = []

        for l in links:
            item = ToyCrawlerItem()
            item['visited_link'] = response.url
            item['extracted_link'] = l.xpath('@href').extract_first()
            yield item

        lis_.append(item)
        df = pd.DataFrame(lis_)

        print('\n\n\n\n\n', df, '\n\n\n\n\n')

        df.to_csv('/Users/user/Desktop/crawled_table.csv', index=False)

但是,上面的代码返回给我:

输出:

extracted_link,visited_link
https://www.extracted-link.com,https://www.example1.com

我试图用以下方法管理None问题值:

   if l == None:
                item['visited_link'] = 'NaN'
            else:
                item['visited_link'] = response.url

但是它不起作用,不知道如何得到(**)

*是一个数据帧,我知道我可以做-o,但我会做数据帧操作。你知道吗

更新

在阅读了@rrschmidt的答案之后,我试图:

def parse(self, response):
    links = response.xpath(".//*[@id='object']//tbody//tr//td//span//a[2]")

    lis_ = []

    for l in links:

        item = ToyItem()

        if len(l) == 0:
            item['visited_link'] = 'NaN'
        else:
            item['visited_link'] = response.url

        #item['visited_link'] = response.url

        item['extracted_link'] = l.xpath('@href').extract_first()

        yield item

        print('\n\n\n Aqui:\n\n', item, "\n\n\n")

   lis_.append(item)
   df = pd.DataFrame(lis_)

   print('\n\n\n\n\n', df, '\n\n\n\n\n')

   df.to_csv('/Users/user/Desktop/crawled_table.csv', index=False)

尽管如此,它还是返回了相同的错误输出。有人能帮我澄清这个问题吗?。你知道吗


Tags: httpscomurldfresponsewwwlinklinks
1条回答
网友
1楼 · 发布于 2024-06-28 20:35:42

据我所知,你的刮刀有两个问题:

  1. 由于parse是为start_urls中的每个元素调用的,并且您正在为每个链接创建和保存一个新的数据帧,因此您正在生成的数据帧将相互覆盖。你知道吗

这就是为什么在crawled_table.csv中总是只有一个结果

解决方法:只创建一次dataframe,并将所有项推入同一dataframe对象。你知道吗

然后在每个parse调用中保存数据帧,以防scraper在完成之前停止。你知道吗

  1. if l == None:不起作用,因为response.xpath如果找不到匹配项,则返回空列表。所以做if len(l) == 0:应该可以

这里的要点是如何构造scraper(代码未经测试!)你知道吗

# -*- coding: utf-8 -*-

class ToySpider(scrapy.Spider):
    name = "toy_example"

    allowed_domains = ["www.example.com"]

    start_urls = ['https:example1.com',
                  'https:example2.com',
                  'https:example3.com']

    df = pd.DataFrame()

    def parse(self, response):
        links = response.xpath(".//*[@id='object']//tbody//tr//td//span//a[2]")
        items = []

        if len(links) == 0:
            item = ToyItem()
            # build item with visited_link = NaN here
            item['visited_link'] = response.url
            item['extracted_link'] = 'NaN'
            items.append(item)
        else:
            for l in links:
                item = ToyItem()
                # build the item as you previously did here
                item['visited_link'] = response.url
                item['extracted_link'] = l.xpath('@href').extract_first()
                items.append(item)

        items_df = pd.DataFrame(items)
        self.df = self.df.append(items_df, ignore_index=True)

        print('\n\n\n\n\n', self.df, '\n\n\n\n\n')
        self.df.to_csv('/Users/user/Desktop/crawled_table.csv', index=False)

        return items

相关问题 更多 >