> 自然
java怎么爬取数据(用java爬取网页)
导语:使用java,如何又快又好的爬取千万级别的数据
近期入职新公司,两周内知识的输入是以往的好几倍,值得将近期学到的东西记录一下。 第一个完成的任务是从HAWQ的数据表中拉取千万级别数量的URL到文件中,程序对不同URL进行爬取相关内容,爬取内容很简单,无非是文章标题、摘要等,比较复杂的是千万级别数量URL的爬取速度以及文件读取方式,保证在速度快的情况下,爬取正确率稳定在80%以上。
设计思路
首先需要明确几个点:
几千万的URL肯定不能直接全部从文件中读取到内存中代码设计分为3步,(从HAWQ中读取写入文件)读文件->URL爬取->写文件(之后写入HAWQ),三步简单来说一定是3个不同线程完成,并且具有相互依赖关系实现
代码采用LinkedBlockingQueue作为文件读取以及写入的缓存队列,每次从文件中读取100条,读完后由爬取线程进行爬取,爬取的同时进行文件的写入。爬取线程数量可自动配置,但必须保证,爬取完成后所有线程正常退出,所以必须有一个完全保障的机制。这里使用CountDownLatch作为一个同步工具,程序启动后立即调用await()方法阻塞,每一个爬取线程完成后,调用countDown()方法减1,直至所有爬取线程完成后都调用此方法,count等于0,然后主线程通过await()方法恢复自己的任务。不论的文件的读取、爬取线程、文件的写入都应该有安全的退出机制。文件的读取和写入分别设置标志位,文件的写入要在文件读取完成后,爬取线程完全退出后,并且队列为空这三种情况下,才能最后退出。以下为具体实现,值得记录并学习这种处理思维,严谨并考虑多种情况。特别注意一点,所有异常都要处理或者抛出,或者会导致线程异常退出,那么主线程就永远无法退出。文件读取线程:
文件读取
爬取线程:
爬取
文件写入线程:
等待所有其他线程结束的线程:
等待所有其他线程结束
本文内容由小纳整理编辑!