【问题标题】:Construct DataFrame from scraped data using Scrapy使用 Scrapy 从抓取的数据中构造 DataFrame
【发布时间】:2017-07-06 02:34:57
【问题描述】:

我在从抓取的数据中构建 csv 类型的数据文件时遇到问题。我已经设法从表中抓取数据,但是在编写它时,我几天都做不到。我正在使用项目并尝试将其写入熊猫数据框。我正在使用项目列表。

import scrapy
from wiki.items import WikiItem
import pandas as pd

class Spider(scrapy.Spider):

name = "wiki"
start_urls = ['https://datatables.net/']

def parse(self, response):

    items = {'Name':[], 'Position':[], 'Office':[], 'Age':[],
        'Start_Date':[],'Salary':[]}

    trs = response.xpath('//table[@id="example"]//tr')
    name = WikiItem()
    pos = WikiItem()
    office = WikiItem()
    age = WikiItem()
    start_data = WikiItem()
    salary = WikiItem()

    name['name'] = trs.xpath('//td[1]//text()').extract()
    pos['position'] = trs.xpath('//td[2]//text()').extract()
    office['office'] = trs.xpath('//td[3]//text()').extract()
    age['age'] = trs.xpath('//td[4]//text()').extract()
    start_data['start_data'] = trs.xpath('//td[5]//text()').extract()
    salary['salary'] = trs.xpath('td[6]//text()').extract()

    items['Name'].append(name)
    items['Position'].append(pos)
    items['Office'].append(office)
    items['Age'].append(age)
    items['Start_Date'].append(start_data)
    items['Salary'].append(salary)

    x = pd.DataFrame(items, columns=['Name','Position','Office','Age',
        'Start_Date','Salary'])

    yield x.to_csv("r",sep=",")

从这段代码中我得到的是这样的;

,Name,Position,Office,Age,Start_Date,Salary
0,"{'name': [u'Tiger Nixon',
      u'Garrett Winters',
      u'Ashton Cox',
      u'Cedric Kelly',
      u'Airi Satou',
      u'Brielle Williamson',
      u'Herrod Chandler',

我得到了名称列,但我得到了 59 次。例如,我有第一行“Tiger Nixon”59 次。我也得到了 59 次位置列,依此类推。而且抓取的数据也不是很好。我是scrapy的新手,愿意接受任何帮助或建议。提前致谢!

编辑:我的 items.py 是这样的;

import scrapy


class WikiItem(scrapy.Item):


name = scrapy.Field()
position = scrapy.Field()
office = scrapy.Field()
age = scrapy.Field()
start_data = scrapy.Field()
salary = scrapy.Field()

【问题讨论】:

    标签: python web-scraping scrapy


    【解决方案1】:

    好的,我不能评论也不能测试你的代码,因为我没有 WikiItem 的定义。但是让我们迭代这个响应,好吗? 你能检查一下你用这段代码得到了什么吗?

    class Spider(scrapy.Spider):
    
        name = "wiki"
        start_urls = ['https://datatables.net/']
    
        def parse(self, response):
    
            trs = response.xpath('//table[@id="example"]//tr')
    
            if trs:
                items = []
                for tr in trs:
                    print tr.xpath('td[2]//text()').extract()
                    item = {
                        "Name": tr.xpath('td[1]//text()').extract(),
                        "Position": tr.xpath('td[2]//text()').extract(),
                        "Office": tr.xpath('td[3]//text()').extract(),
                        "Age": tr.xpath('td[4]//text()').extract(),
                        "Start_Date": tr.xpath('td[5]//text()').extract(),
                        "Salary": tr.xpath('td[6]//text()').extract()
                    }
                    items.append(item)
    
    
                x = pd.DataFrame(items, columns=['Name','Position','Office','Age',
                    'Start_Date','Salary'])
    
                yield x.to_csv("r",sep=",")
    

    【讨论】:

    • 谢谢!我编辑了问题,添加了 items.py。当我尝试你的代码时,我得到了 59 行。每一行都有完整的姓名、职位、办公室、年龄、开始日期和薪水信息,每一行都是相同的。我认为我的问题来自 items.py。
    • 测试新版本,如果它更好,请告诉我。
    • 它正在工作!非常感谢。我想问题出在字典的使用上。
    • 是的。并检查元素 xpath 从 //td[1]//text()td[1]//text() 的微小变化。我删除了// 以使此xpath 相对于tr 而不是整个文档;)如果它正在运行,您可以投票响应吗? ;) 最好的问候。
    • 我的声望达到 15 时我会的!最好的!
    【解决方案2】:

    我知道这与问题提出的用例并不完全相关,但我觉得它与问题的标题有关:如何在 scrapy Spider 中返回 pd DataFrame 对象? p>

    上下文:

    如果你试图在scrapy蜘蛛中导出一个pd.DataFrame对象,如果你直接声明yield df,例如:

    import scrapy 
    import json
    import pandas as pd 
    
    class Spider(scrapy.Spider): 
       start_urls = ['mywebsite.com'] 
    
       def parse(self, response):
           #Let us assume mywebsite.com contains a script tag with JSON data rendered serverside
           script = response.xpath('//script[@id="windowData"]/text()').extract_first()
          
           data = json.loads(script)
    
           #Construct dataframe from dictionary
           df = pd.DataFrame.from_dict(data['anInterestingPieceOfData'])
     
           yield df
    

    这将返回一个错误,即您尝试生成的东西不是Request, BaseItem, dict or None,而是DataFrame

    解决方案

    所以问题变成了,如何将DataFrame 对象转换为某种字典?这与您的提要导出格式无关(如果蜘蛛输出的是 CSV 或 JSON 或其他格式)。

    你可以使用 pandas 中的任何东西to_csvto_json,但我发现一个灵活的选择是使用to_dict,例如使用yield from 语法:

    yield from self.df.to_dict(orient="records")
    

    【讨论】:

      猜你喜欢
      • 2020-09-12
      • 2015-02-05
      • 2013-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-23
      • 2019-02-13
      • 2017-01-06
      相关资源
      最近更新 更多