Java爬虫,爬取竞彩网数据并按指定格式输出到excel表格中

首先需要下载相关的依赖包,我用的是eclipse,直接百度maven然后搜索相应的依赖放到pom文件中就行了。

爬取的网址为:http://info.sporttery.cn/football/match_result.php

代码的大致步骤为:

1.用scanner输入需要爬取的起始日期和截止日期

2.用URL和openStream将起始日期到截止日期的网页下载到本地,由于可能会有很多页,所以就需要先知道page数再按照page逐页下载。

3.用indexOf("html")提取本地的HTML文件,并按照名称排序。

4.用Jsoup解析HTML文件,表头只需要首次解析时提取,表内容则每次都需要读取。

5.用XSSFWorkbook 将解析的文本写入excel。

6.用delete方法删除已下载到本地的HTML文件。


完整代码如下:

扫描二维码关注公众号,回复: 8494020 查看本文章

package com.xlh.bd.internal.service;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Scanner;

import org.apache.commons.io.FileUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class SpiderSgkjService {
/**
* 爬取500网竞彩足球的赛果开奖数据
*/
public static String startDate = null; //起始日期
public static String endDate = null;   //截止日期
public static List<String> result = new ArrayList<String>(); 
public static int titleLen = 0;
// volatile boolean keepRunning = true; //volatile保证了线程可以正确的读取其他线程写入的值
// private final Object lockobj = new Object();
public static String url = "http://info.sporttery.cn/football/match_result.php?page=";
public static List<String> urlList = new ArrayList<String>(); //网页列表
public static List<String> timeList = new ArrayList<String>(); //时间列表
public static int pageCount = 0;

public void getUrlList() throws IOException{
DateFormat format2 = new SimpleDateFormat("yyyy-MM-dd"); //字符串时间格式
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入起始日期,格式为yyyy-MM-dd:");
    startDate = sc.next();
    @SuppressWarnings("unused")
Date date = null;
try {
date = (Date)format2.parse(startDate);
} catch (ParseException e) {
System.out.println("起始日期输入格式错误");
e.printStackTrace();
}
   
    Scanner sc2 = new Scanner(System.in);
    System.out.println("请输入截止日期,格式为yyyy-MM-dd:");
    endDate = sc2.next();
    @SuppressWarnings("unused")
    Date date2 = null;
try {
date2 = (Date)format2.parse(endDate);
} catch (ParseException e) {
System.out.println("截止日期输入格式错误");
e.printStackTrace();
}
    sc.close();
    sc2.close();
    String url2 = url +1+"&search_league=0&start_date="+startDate+"&end_date="+endDate;
    Document doc = Jsoup.connect(url2).get(); //从URL直接加载 HTML 文档
//     Element content = doc.getElementById("headerTr");//得到id为headerTr的所有东西
        Elements links = doc.getElementsByClass("m-page");
        for (Element element : links) {
        String linkText2 = element.text();//得到<td>...</td>里面的内容
            int first = linkText2.indexOf("有");//要提取的字符串起始位置
            int last = linkText2.indexOf("场");//要提取的字符串终止位置
            pageCount = (int) Math.ceil(Double.parseDouble(linkText2.substring(first+1, last))/30);
            System.out.println("共有"+pageCount+"页需要爬取,请耐心等耐!");
        }
    }

public class ReadHtml extends Thread {
private String s = null;
public ReadHtml(String s){
       this.s = s ;
   }
public void run(){
System.out.println("正在下载"+s);
for (int i=1; i<=pageCount; i++) {
String url2 = url + i +"&search_league=0&start_date="+startDate+"&end_date="+endDate;
System.out.println("Page" + i + "starts!");
try {
      File dest = new File("src/page" + i +".html"); 
               InputStream is; //接收字节输入流
FileOutputStream fos = new FileOutputStream(dest); //字节输出流

    URL temp = new URL(url2); //加载网页
           is = temp.openStream();  
           
           BufferedInputStream bis = new BufferedInputStream(is);//为字节输入流加缓冲            
           BufferedOutputStream bos = new BufferedOutputStream(fos);//为字节输出流加缓冲


           int length;    
           byte[] bytes = new byte[1024*20];
           while((length = bis.read(bytes, 0, bytes.length)) != -1){
               fos.write(bytes, 0, length);
           }
           bos.close();
           fos.close();
           bis.close();
           is.close();
sleep(10); //间隔0.01秒
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

public static List<File> listHtmlFiles(String path){
        File file = new File(path); //读取本地html的路径        
        File[] array = file.listFiles(); //用于存储路径下的文件名
        List<File> array2 = new ArrayList<File>();
        for(int i=0;i<array.length;i++){
            if(array[i].isFile()&&array[i].getName().indexOf("html")>-1){
            array2.add(array[i]);
            }        
        }
        List<Integer> num = new ArrayList<Integer>();
        for(int i=0;i<array2.size();i++){
        String string = array2.get(i).toString();
        int first = string.indexOf("page");
            int last = string.indexOf(".");
        num.add(Integer.parseInt(string.substring(first+"page".length(), last)));
        }
        Collections.sort(num); //按值排序
        List<String> num2 = new ArrayList<String>();
        for (Integer integer : num) {
        num2.add("page"+String.valueOf(integer)+".html");
}
        List<File> array3 = new ArrayList<File>();
        for(int i=0;i<num2.size();i++){
        for (File file2 : array2) {
        if(file2.toString().contains(num2.get(i))) array3.add(file2);
}
        System.out.println(array3.get(i));
        }
return array3;
}

    public static void getLocalhtml(String path) { //解析本地的html 
    List<File> array = listHtmlFiles(path);
        //循环读取并解析这些文件
        for(int i=0; i<array.size(); i++){
            try{
                //文件名字
                System.out.println("正在解析网址:" + array.get(i).getName()+"!");
                //下面开始解析本地的html
                Document doc = Jsoup.parse(array.get(i), "gb2312"); 
                Elements links = doc.getElementsByClass("match_list");//分离出class="match_list"的所有东西
                
                Element link = links.get(0);
            if(i==0){ //仅第一次需要读取表头
                Elements links2 = link.getElementsByTag("th");                        
                    List<String> title = new ArrayList<String>();
                    for (Element element : links2) {
                        String linkText2 = element.text();//得到<th>...</th>里面的内容
                        title.add(linkText2);
                        result.add(linkText2);
    }                
                    titleLen = title.size();
//                    System.out.println(titleLen);                    
            }
           
                Element link2 = links.get(1);
                Elements links22 = link2.getElementsByTag("td");
                for (int j=0; j<links22.size()-2; j++) { //读取表的内容
                    String linkText22 = links22.get(j).text();//得到<td>...</td>里面的内容
                    result.add(linkText22);  
}
                System.out.println(array.get(i).getName()+"解析完毕!");
             } catch (Exception e) {
                    System.out.println("网址:" + array.get(i).getName() + "解析出错");
                    e.printStackTrace();
                    continue;
                }
        }
    }
    
    public static void writeExcel(String path) throws IOException{ //将网页数据写入excel
    getLocalhtml(path);
    //创建一个文件
File file2 = new File(path+"pioTest2.xlsx");
file2.createNewFile();
//将excel数据存盘
FileOutputStream stream2 = FileUtils.openOutputStream(file2);
//创建excel工作簿(最后需要往里写数据)
XSSFWorkbook workbook2 = new XSSFWorkbook();
XSSFSheet sheet2 = workbook2.createSheet();//创建sheet
System.out.println("正在写入excel!");
for (int i = 0; i < result.size()/titleLen; i++) { //创建行
XSSFRow row2 = sheet2.createRow(i);
for (int j = i*titleLen; j < (i+1)*titleLen; j++) { //创建单元格
XSSFCell cell2 = row2.createCell(j-i*titleLen);
cell2.setCellValue(result.get(j));
}
}
workbook2.write(stream2);
stream2.close();
workbook2.close();
System.out.println("写入完毕!");
    }


    public static void deleteHtml(String path){ //删除path下的html文件
    File file = new File(path);
    File[] files = file.listFiles();
    for (File file2 : files) {
if(file2.getName().indexOf("html")>-1) file2.delete();
}
    }
    
    public static void main(String[] args) throws ParseException, IOException, InterruptedException {
    SpiderSgkjService ss = new SpiderSgkjService();
    ss.getUrlList();
    ReadHtml rt = ss.new ReadHtml("500网竞彩足球赛果开奖数据!");
    rt.start();
    try {
    rt.join(); //保证网页读取完毕
    System.out.println();
    } catch (InterruptedException e) {
    e.printStackTrace();
     }
    String path = "D:\\xlh\\src\\";
    writeExcel(path);
    deleteHtml(path);
    }

}

至于Thread是为了可以多线程爬取,比如把football换成basketball就可以再同时爬取篮球的数据,这里就没有加上,有需要的自己将url中的football设置成变量,同时在main函数中多生成一个ReadHtml类和rt同时start就行了。



发布了49 篇原创文章 · 获赞 95 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/Trisyp/article/details/78192730