爬虫抓取分页数据的简单实现

article/2025/9/4 23:00:21
爬虫抓取分页数据的简单实现

昨天,我们已经利用Jsoup技术实现了一个简单的爬虫,原理很简单,主要是要先分析页面,拿到条件,然后就去匹配url,采用dome解析的方式循环抓取我们需要的数据,从而即可轻松实现一个简单的爬虫。那么,昨天我们说了,我们昨天只是爬取了一页的数据也就是第一页的数据,若想获取分页的全部数据该怎么写呢?正好,今天朋友托我帮忙买一种药,说是她那边没有,于是,我就查询了一下佛山的各大药店,利用我们刚学的爬虫技术,我们今天就来实现一下爱帮网上佛山药店的分布列表。

一、需求分析

首先,我们登陆爱帮网,选择城区以及输入关键字,我们输入的是“药店”,点击搜索按钮,我们打开控制台,观察头信息,如下图:

 

我们通过观察可以看到请求的url地址以及参数;其实直接看地址栏就可以看得出来,我们点击第二页发现其他参数都不变,只有参数p的值随页码的变化而变化。那么,这样以来,我们就可以知道每一页的请求地址其实都是一样的,只要改变p的值即可,然后我们看页面总页数只有8页,数据量不大,写个循环循环8次即可。下面我们就来开始实现,依然在昨天的代码的基础上改一改即可。

 

二、开发

1、我们首先需要改一下我们的业务实现类,因为取值的方式已经不一样了,如下图:

我们要去的class为aside中的内容,同样是拿到<a>标签,但是我们观察得知页面有很多的<a>标签,我们要取得我们需要的,如下图:

/** 提取结果中的链接地址和链接标题,返回数据*/for(Element result : results){Elements links = result.getElementsByTag("a");//可以拿到链接for(Element link : links){if(link.siblingElements().hasClass("num")){String id = link.siblingElements().text();String linkText = link.text();LinkTypeData data1 = new LinkTypeData();if(id!=null && linkText!=null){data1.setId(id);data1.setLinkText(linkText);}datas.add(data1);}if(link.parent().parent().hasClass("part1")){LinkTypeData data2 = new LinkTypeData();String address = link.parent().siblingElements().text();if(address!=null){data2.setSummary(address);}datas.add(data2);}if(link.parent().siblingElements().tagName("span").hasClass("biztel")){LinkTypeData data3 = new LinkTypeData();String telnum = link.parent().siblingElements().tagName("span").text();if(telnum!=null){data3.setContent(telnum);}datas.add(data3);}}// 对取得的html中的&nbsp;出现问号乱码进行处理/*linkText = new String(linkText.getBytes(),"GBK").replace('?', ' ').replace(' ', ' ');String id = link.parent().firstElementSibling().text();id = new String(id.getBytes(),"GBK").replace('?', ' ').replace(' ', ' ');String address = link.parent().nextElementSibling().text();address = new String(address.getBytes(),"GBK").replace('?', ' ').replace(' ', ' ');String code = link.parent().lastElementSibling().text();code = new String(code.getBytes(),"GBK").replace('?', ' ').replace(' ', ' ');*//*data.setSummary(address);data.setContent(code);data.setId(id);*/}return datas;}

 

我们在昨天的代码基础上进行了更改。这样就取得了我们想要的数据。

三、测试

接下来我们就可以改一下我们的测试类,我们需要循环8次,而每一次获取到的数据我们都存进一个新的集合中,然后最后再拿出新的集合的数据写进Excel。

/*** 不带查询参数* @author AoXiang* 2017年3月21日*/@org.junit.Testpublic void getDataByClass() throws IOException{List<LinkTypeData> newList = new ArrayList<LinkTypeData>();for(int i=1;i<=8;i++){Rule rule = new Rule( "http://www.aibang.com/?area=bizsearch2&cmd=bigmap&city=%E4%BD%9B%E5%B1%B1&a=%E5%8D%97%E6%B5%B7%E5%8C%BA&q=%E8%8D%AF%E5%BA%97&as=5000&ufcate=&rc=1&zone=&quan=&fm=&p="+i,null,null,"aside", Rule.CLASS, Rule.POST);List<LinkTypeData> datas = ExtractService.extract(rule);for(int j=0;j<datas.size();j++){newList.add(datas.get(j));}}// 第一步,创建一个webbook,对应一个Excel文件  HSSFWorkbook wb = new HSSFWorkbook();  // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet  HSSFSheet sheet = wb.createSheet("佛山药店");  // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short  HSSFRow row = sheet.createRow((int) 0);  // 第四步,创建单元格,并设置值表头 设置表头居中  HSSFCellStyle style = wb.createCellStyle();  style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式  HSSFCell cell = row.createCell((short) 0);  cell.setCellValue("序号");  cell.setCellStyle(style);  cell = row.createCell((short) 1);  cell.setCellValue("药店名称");  cell.setCellStyle(style);  cell = row.createCell((short) 2);  cell.setCellValue("地址");  cell.setCellStyle(style);  cell = row.createCell((short) 3);  cell.setCellValue("电话");  cell.setCellStyle(style);  for(int m=0;m<newList.size();m++){// 第五步,写入实体数据row = sheet.createRow((int)m  + 1);  // 第四步,创建单元格,并设置值  row.createCell((short) 0).setCellValue(newList.get(m).getId());  row.createCell((short) 1).setCellValue(newList.get(m).getLinkText());  row.createCell((short) 2).setCellValue(newList.get(m).getSummary());  row.createCell((short) 3).setCellValue(newList.get(m).getContent());  }// 第六步,将文件存到指定位置  try  {  FileOutputStream fout = new FileOutputStream("F:/佛山药店.xls");  wb.write(fout);  fout.close();  }  catch (Exception e)  {  e.printStackTrace();  }  }

我们运行一下看结果:

 好了,我们已经拿到我们需要的数据了,然后就可以对这些数据进行分析,为我么所用。

其实,这只是一个简单的网站,一般现在的网站有些分页是JS动态获取的,我们看不到分页信息,那么,这就需要我们灵活应变,爬虫技术也不是只有这一种,然而万变不离其宗,掌握了要领和方法,相信不会有任何困难。

源码就不用上传了,有兴趣的同学可以参考一下,其实就是改了两处地方。

如果您对代码有什么异议欢迎您的留言,我们一起交流!

posted on 2017-03-22 17:58  ++i和i++ 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/ao-xiang/p/6601228.html


http://chatgpt.dhexx.cn/article/B9ar0ljf.shtml

相关文章

PHP爬虫抓取网页数据

2019年我接触到PHP爬虫的时候&#xff0c;我最开始是懵的。还有人用php来写爬虫&#xff1f; 一个月之后&#xff0c;嗯~全世界最好的语言写全世界最好的爬虫&#xff0c;真香&#xff01;而在7月15这一个日常加班的晚上&#xff0c;做完手头的活&#xff0c;我寻思着写会儿php…

网络爬虫的基本结构是什么?如何建立网络爬虫抓取数据?

摘要&#xff1a;互联网上有很多丰富的信息可以被抓取并转换成有价值的数据集&#xff0c;然后用于不同的行业。比如企业用户利用电商平台数据进行商业分析&#xff0c;学校的师生利用网络数据进行科研分析等等。那么&#xff0c;除了一些公司提供的一些官方公开数据集之外&…

利用EXCEL进行数据爬虫

说到爬虫&#xff0c;相信大家出现在脑海中的一定是python。python在最近几年确实热火朝天&#xff0c;对于不会编程人员来说&#xff0c;利用好EXCEL一样也可以爬取一些简单的数据&#xff0c;并且方式非常简单。 1.爬取东方财富网上基金信息。网址为&#xff1a;基金收益排行…

利用Excel数据爬虫

1、在Excel里数据里打开自网站。 2、选择高级部分 URL部分和URL预览填写为目标&#xff08;需要爬取数据的网址&#xff09;的URL地址 命令超时选择1分钟即可。 HTTP请求标头参数 第一步点击网络 第二部点击消息头部 第三部找到User-Agent的value复制 3、最后点击加载 就…

爬虫抓取网络数据时经常遇到的六种问题

随着互联网时代的不断发展&#xff0c;爬虫采集已经成为了目前最为主流的数据获取方式。使用爬虫软件自动从网站中提取数据可以节省大量的时间和精力。接下来就一起来看看爬虫抓取网络数据时经常遇到的六种问题吧&#xff1a; 1.IP阻止 IP阻止是指网站所有者主动阻止用户的IP地…

Jsoup实现网络爬虫抓取数据

Jsoup实现网络爬虫抓取数据 在编写一个软件&#xff0c;例如关于教务软件的时候&#xff0c;需要获取学校官网的一些新闻信息来充实自己的软件&#xff0c;而又不会专门提供相关的api接口&#xff0c;此时就需要我们自己动手来抓取感兴趣的信息。有人会问抓取网站的信息是否会…

Java爬虫,数据采集经验分享

公司要求我采集网页中的某些数据&#xff0c;以下是我采集的步骤和思路&#xff0c;比较基础。 一.首先我是通过抓取网页源代码的方式&#xff0c;根据源代码&#xff0c;获取各种标签中的数据 public class GetData {//数据抓取核心类// 获取网页数据/** param url:目标网址…

Python爬虫抓取数据时怎么防止ip被封

大数据公司在做数据分析的时候&#xff0c;对目标网站频繁访问很容易触发网站的反爬机制&#xff0c;因此如果想要突破限制只能使用动态ip频繁切换地址模拟真实客户访问网站才能起到防封效果。比如在做数据抓取的时候报错403等限制访问&#xff0c;大概率是因为ip被限。本文总结…

爬虫入门——数据抓取

学习爬虫&#xff0c; 最初的操作便是模拟浏览器向服务器发出请求。使用一下库实现此请求 1.urllib库的使用 urllib 库是Python 内置的HTTP 请求库&#xff0c;包含以下四个模块&#xff1a; 1.request&#xff1a;http请求模块 2.error&#xff1a;异常处理模块 3.parse&#…

ts全局变量定义

参照已有全局变量定义 src/global.d.ts /** Author: hongbin* Date: 2022-10-21 08:49:42* LastEditors: hongbin* LastEditTime: 2022-10-21 09:09:08* Description:全局类型&#xff0c;变量&#xff0c;常量*/ //全局变量 declare let Hong: string; declare const BIN: s…

C++中的全局变量声明和定义

1.全局变量 全局变量在整个源文件的作用域都是有效的&#xff0c;只需要在一个源文件中定义全局变量&#xff0c;在其他不包含全局变量定义的源文件中用extern关键字再次声明这个全局变量即可。 也可以在一个源文件中定义这个全局变量&#xff0c;在头文件中用extern关键字再…

c语言全局变量(c语言全局变量怎么定义)

菜鸟提问:GCCE编译环境下&#xff0c;汇编函数如何使用C全局变量汇编化了 首先要在C程序中用extern申明该变量为全局变量&#xff0c;再在汇编程序中用extern "变量名"来导入&#xff0c;注意&#xff0c;汇编中如果直接使用"mov eax,变量名"表示的是将该变…

C++全局变量的声明和定义

参考&#xff1a; http://wrchen.blog.sohu.com/71617539.html &#xff08;1&#xff09;编译单元&#xff08;模块&#xff09; 在VC或VS上编写完代码&#xff0c;点击编译按钮准备生成exe文件时&#xff0c;编译器做了两步工作&#xff1a; 第一步&#xff0c;将每个.cpp(.c…

【Vue】全局变量的定义及使用

首先声明Vue使用全局变量的方法有很多&#xff0c;以下只是个人觉得比较简洁的2种。其中两者的第一步操作相同&#xff0c;即&#xff1a; 创建全局变量文件Global.vue&#xff0c;内容如下&#xff1a; <script>const name ZhangSan; //名称const address No.20, Ta…

VC++中全局变量的问题(转)

全局变量一般这样定义&#xff1a;1。在一类的.cpp中定义 int myInt;然后再在要用到的地方的.cpp里extern int myInt&#xff1b;这样就可以用了。 2。在stdafx.cpp中加入:int myInt;然后在stdafx.h中加入:extern int myInt这样定义以后无论在什么文件中都是可见的. 3。比较规…

LINUX c语言 定时显示CPU,内存和硬盘的使用率

/* 写在完成后&#xff0c;查找了很多资料&#xff0c;看到了很多方法&#xff0c;也看了部分top的源码&#xff0c;最终选择了这几种混合的方式来写&#xff0c;可能有更优解&#xff0c;不过目前这样应该够用。 --2020/12/15-- Simon */需求&#xff1a;定期获取CPU&#x…

crontab做系统定时任务命令

crontab做系统定时任务命令&#xff1a; 给系统设置一个定时的任务&#xff0c;相当于一个闹钟 我们每天的0点去做一些清理工作&#xff0c;自检工作&#xff0c;重要数据存盘备份工作&#xff0c;一个组里面很多同时都在提交代码&#xff0c;git作为代码管理工具&#xff0c;每…

c语言如何让函数一直执行,C语言如何实现在每天某个特定时间执行某个函数?

慕仙森 Windows提供了定时器&#xff0c;帮助编写定期发送消息的程序。定时器一般通过一下两中方式通知应用程序间隔时间已到。⑴ 给指定窗口发送WM_TIMER消息&#xff0c;也就是下面的给出在窗口类中使用的方法。⑵ 调用一个应用程序定义的回调函数&#xff0c;也就是在非窗口…

HashedWheelTimer时间轮定时任务原理分析

一、示例代码 HashedWheelTimer时间轮是一个高性能&#xff0c;低消耗的数据结构&#xff0c;它适合用非准实时&#xff0c;延迟的短平快任务&#xff0c;例如心跳检测。 时间轮是一种非常惊艳的数据结构。其在Linux内核中使用广泛&#xff0c;是Linux内核定时器的实现方法和基…

SpringMVC中定时任务配置

在项目中使用定时任务是常有的事&#xff0c;比如每天定时进行数据同步或者备份等等。 以前在从事C语言开发的时候&#xff0c;定时任务都是通过写个shell脚本&#xff0c;然后添加到linux定时任务中进行调度的。 现在使用SpringMVC之后&#xff0c;一起都变得简单了o(∩_∩)…