为了学习scrapy,我试图从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
是数据框,我知道我可以做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)
,但我会做数据框操作。
更新
阅读@rrschmidt后,我试着:
{{1}}
然而,它仍然给我带来了相同的错误输出。有人可以帮我澄清一下这个问题吗?
答案 0 :(得分:0)
据我所知,你的刮刀存在两个问题:
parse
中的每个元素调用start_urls
,并且您正在为每个链接创建并保存新的数据帧,您生成的数据帧将相互覆盖。 这就是为什么你的crawled_table.csv
解决方案:只创建一次数据帧并将所有项目推送到同一个数据框对象中。
然后在每个parse
调用中保存数据框,以防刮刀在完成之前必须停止。
if l == None:
将无效,因为response.xpath
会返回空列表。所以做if len(l) == 0:
应该做
醇>
这里有一个要点我将如何构建刮刀(代码未经过测试!)
# -*- 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