zoukankan      html  css  js  c++  java
  • ruby获取网页链接,下载excel文件

    ruby获取网页链接,下载excel文件

    需求:

    获取http://123.57.212.98/html/tm/29/38/68/68.html网站的历届詹天佑奖的excel名单,并且把excel格式转换为csv格式。

    第一步 : 首先获取到此页面所有的excel表个文件的连接,并且下载到本地,思路是用一个队列来放符合要求的所有链接,从队头取出链接,根据这个链接得到一个新的页面page,再解析此page,把此页面的所有有用的链接放入如队列。直到队列为空。(这里有用的链接是能够到达 可以获取excel文件的页面)

    require "yomu"
    require "mechanize"
    require "open-uri"
    
    $queue=[]
    $queueFile=[]
    $queue.push({"zhantianyou" => 'http://123.57.212.98/html/tm/29/38/68/68.html'})
    =begin 
        下载所有文件的思路:
        有一个入口的URl,和一个队列,队列中最开始只有一个此入口url,
        根据这个url,获取此页面的所有链接,把链接放到队列中,同时过滤出来 需要的表格url,把表格url保存下来。
        
    =end
        
        
        # queue对列中放的是一个 {网页标题 => 网页url } 的散列
    while !$queue.empty?
        url=""
        $queue.shift.each_value do |value|
            url=value
        end
       begin
        page=Mechanize.new.get(url)
       rescue 
           puts "---------------------->>>>  #{url} 不能访问"
       end
       
        page.links.each do |link|
            if link.text.include?('.xls')# 将有用的表格url存起来
                puts link.text
                $queueFile.push({link.text => link.href})
            elsif link.text.include?('詹天佑奖获奖工程及获奖单位名单') || link.text.include?('下一页')# 有用的链接放到队列中,便于下一次访问
                #puts link.text
                $queue.push({link.text=>link.href})
            end
        end
    end
    
    # 根据 url 下载到本地
    while !$queueFile.empty?
        url=$queueFile.shift
        url.each do |key,value|
            puts key
            File.open('./'+key,"w") do |io|
                io.puts(open(value).read)
            end
        end
    end
    
    

    第二步: excel文件可以直接另存为csv文件,但是格式不是太好,并且会莫名奇妙的少一些数据,后来发现还可以把excel文件另存为html 文件,这样试了试,发现转成的html文件的格式很好,数据也没有错误,非常适合提取有用的信息。看下面的代码

    require "yomu"
    require "nokogiri"
    def getContent(page,dir,io)
        puts dir
        # 得到历届詹天佑奖的时间
        dir =~ /第.+?届/
        title = $&
        dir =~ /[0-9][0-9][0-9][0-9]年度/
        title1=$&
        if title1==nil
            title1=""
        end
    
        title+=title1
        line=[]
        temp=""
        i=0
        # 获取含符合规范的td,  下面xpath的意思: 匹配含有rowspan 属性的td,或者 不含rowspan 以及 不含colspan 属性的td
        # 为了展现xpath not 的用法,下面的语句有些多余
        page.xpath("//td[ @rowspan or not(@rowspan or @colspan) ]").each do |td|
            # 去掉一些不需要的内容,如表头,
            if td.content =~ /[0-9]$/ || !td.to_s.include?('x:str') || td.content =~ /序号|工程名称|参建单位|编号/
                next
            end
            if td.to_s.include?('rowspan')# 代表着一行开始了
                temp.slice!(-1)# 删除最后一个顿号
                temp.gsub!(/[0-9]-/,"")# 剔除多余的字符
                i+=1
                if i>1# i==1 代表着此表的第一行,由于同一列分布在多行,只有处理到下一行的开始部分才把这一行的数据写入文件,所以i==1时,第一行的数据还没有结束,不能写入文件
                    io.puts(temp+","+title.to_s)# 将此行写入文件
                    puts "#{i}   #{temp},#{title.to_s}"
                end
                temp=""
                temp <<td.content+","
            else
                temp<<td.content+"、"# 把分布在多行的列连接成一行
            end
        end
        # 处理最后一行数据
        temp.slice!(-1)
        temp.gsub!(/[0-9]-/,"")
        io.puts(temp+","+title.to_s)# 把最后一行的数据写入文件
        puts "#{i+1}   #{temp},#{title.to_s}"
    end
    
    io=File.open("./詹天佑奖.csv","w+")# 准备写入数据的文件
    io.puts("工程名称,参建单位,时间")# th
    Dir.open("./詹天佑/詹天佑html/").each do |dir|# 遍历此文件夹下的所有文件
        if dir=="."||dir==".."# 过滤本目录和上级目录
            next
        end
        f=File.open('./詹天佑/詹天佑html/'+dir)
        page=Nokogiri::HTML(f)
        getContent(page,dir,io)
        f.close
    end
    io.close
    
    
    

    总结:

    以前需要把excel表格文件转换为csv文件时,都是直接把excel文件另存为csv文件,最后再处理格式,

    其实转换为html文件更方便处理一些。

  • 相关阅读:
    临时表的汇总
    数据仓库逻辑建模
    在Eclipse下搭建Android开发环境教程(1)
    SQL Server数据库锁的引入的缘由
    C#图片处理基本应用(裁剪,缩放,清晰度,水印)(转)
    Default on textbox
    引用 几种绑定DropdownList的方法
    Jquery示例
    MSSql数据库锁
    C# 常用算法
  • 原文地址:https://www.cnblogs.com/dccmmtop/p/6928657.html
Copyright © 2011-2022 走看看