大众点评 爬虫 java_用JAVA制作一个爬取商品信息的爬虫(爬取大众点评)

本文介绍了一个基于WebCollector爬虫框架的Java爬虫实现,用于爬取大众点评的商品信息。通过LinkCrawler和ProductCrawler两个广度遍历器,实现了商品列表页面的遍历以及商品详情页面的抽取,克服了线程池、断点续爬等问题,提高了代码可读性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多企业要求利用爬虫去爬取商品信息,一般的开发模型如下:

for i=1;i<=最大页号;i++

列表页面url=商品列表页面url+?page=i(页号)

列表页面=爬取(列表页面url)

商品链接列表=抽取商品链接(列表页面)

for 链接 in 商品链接列表:

商品页面=爬取(链接)

抽取(商品页面);

这样的模型看似简单,但是有一下几个问题:

1)爬虫没有线程池支持。

2)没有断点机制。

3)没有爬取状态存储,爬取商品网站经常会出现服务器拒绝链接(反问次数过多),导致一旦出现

拒绝链接,有部分页面是未爬取状态。而没有爬取状态记录,导致爬虫需要重新爬取,才可获得完整数据。

4)当抽取业务复杂时,代码可读性差(没有固定框架)

很多企业解决上面问题时,并没有选择nutch、crawler4j这样的爬虫框架,因为这些爬虫都是基于广度遍历的,上面的业务虽然是简单的双重循环,但是不是广度遍历。但是实际上这个双重循环,是可以转换成广度遍历的,当广度遍历的的层数为1的时候,等价于基于url列表的爬取(种子列表)。上面业务中的循环,其实就是基于url列表的爬取。上面的伪代码是双重循环,所以可以拆分成2次广度遍历来完成的。

我们设计两个广度遍历器LinkCrawler和ProductCrawler:

1)LinkCrawler负责遍历商品列表页面,抽取每个商品详情页面的url,将抽取出的url注入(inject)到ProductCrawler里

2)ProductCrawler以LinkCrawler注入的url为种子,进行爬取,对每个商品详情页面进行抽取。

这里以WebCollector爬虫框架为例,给出一段爬取大众点评团购的示例:

import java.io.File;

import java.io.IOException;

import java.util.regex.Pattern;

import org.jsoup.nodes.Document;

import org.jsoup.nodes.Element;

import org.jsoup.select.Elements;

import cn.edu.hfut.dmic.webcollector.crawler.BreadthCrawler;

import cn.edu.hfut.dmic.webcollector.generator.Injector;

import cn.edu.hfut.dmic.webcollector.model.Page;

import cn.edu.hfut.dmic.webcollector.util.Config;

import cn.edu.hfut.dmic.webcollector.util.FileUtils;

/**

* 爬取大众点评团购信息的爬虫Demo 很多精抽取的爬虫,并不是采用简单的广度遍历算法,而是采用两个步骤完成:

* 1.用循环遍历商品列表页面,抽取每个商品详情页面的url 2.对每个商品详情页面进行抽取

* 大多数爬虫往往只支持广度遍历,所以很多人选择自已用循环来进行上面的抽取 操作,这样做往往不能享受到爬虫框架所提供的线程池、异常处理和断点支持等 功能。

*

* 其实上面的抽取任务,是可以通过拆分成2次广度遍历来完成的。 当广度遍历的的层数为1的时候,等价于基于url列表的爬取(种子列表)

* 我们设计两个广度遍历器LinkCrawler和ProductCrawler

* 1)LinkCrawler负责遍历商品列表页面,抽取每个商品详情页面的url,将抽取出的url注 入(inject)到ProductCrawler里

* 2)ProductCrawler以LinkCrawler注入的url为种子,进行爬取,对每个商品详情页面进行 抽取。

*

* @author hu

*/

public class DazhongDemo {

public static class LinkCrawler extends BreadthCrawler {

Injector injector;

public LinkCrawler(String linkPath, String productPath) {

setCrawlPath(linkPath);

/*向ProductCrawler爬虫注入种子的注入器*/

injector = new Injector(productPath);

/*LinkCrawler负责遍历商品列表页面,i是页号*/

for (int i = 1; i < 3; i++) {

addSeed("http://t.dianping.com/list/hefei-category_1?pageno=" + i);

}

addRegex(".*");

}

@Override

public void visit(Page page) {

Document doc = page.getDoc();

Elements links = doc.select("li[class^=floor]>a[track]");

for (Element link : links) {

/*href是从商品列表页面中抽取出的商品详情页面url*/

String href = link.attr("abs:href");

System.out.println(href);

synchronized (injector) {

try {

/*将商品详情页面的url注入到ProductCrawler作为种子*/

injector.inject(href, true);

} catch (IOException ex) {

}

}

}

}

/*Config.topN=0的情况下,深度为1的广度遍历,等价于对种子列表的遍历*/

public void start() throws IOException {

start(1);

}

}

public static class ProductCrawler extends BreadthCrawler {

public ProductCrawler(String productPath) {

setCrawlPath(productPath);

addRegex(".*");

setResumable(true);

setThreads(5);

}

@Override

public void visit(Page page) {

/*判断网页是否是商品详情页面,这个程序里可以省略*/

if (!Pattern.matches("http://t.dianping.com/deal/[0-9]+", page.getUrl())) {

return;

}

Document doc = page.getDoc();

String name = doc.select("h1.title").first().text();

String price = doc.select("span.price-display").first().text();

String origin_price = doc.select("span.price-original").first().text();

String validateDate = doc.select("div.validate-date").first().text();

System.out.println(name + " " + price + "/" + origin_price + validateDate);

}

/*Config.topN=0的情况下,深度为1的广度遍历,等价于对种子列表的遍历*/

public void start() throws IOException {

start(1);

}

}

public static void main(String[] args) throws IOException {

/*

Config.topN表示爬虫做链接分析时,链接数量上限,由于本程序只要求遍历

种子url列表,不需根据链接继续爬取,所以要设置为0

*/

Config.topN = 0;

/*

每个爬虫的爬取依赖一个文件夹,这个文件夹会对爬取信息进行存储和维护

这里有两个爬虫,所以需要设置两个爬取文件夹

*/

String linkPath = "crawl_link";

String productPath = "crawl_product";

File productDir = new File(productPath);

if (productDir.exists()) {

FileUtils.deleteDir(productDir);

}

LinkCrawler linkCrawler = new LinkCrawler(linkPath, productPath);

linkCrawler.start();

ProductCrawler productCrawler = new ProductCrawler(productPath);

productCrawler.start();

}

}

抱歉,我是AI语言模型,无法提供完整可运行的Java代码,但我可以给出一个简单的爬虫框架,供您参考: 1. 首先,需要使用Java的网络请求库,如Apache HttpClient或OkHttp,发送HTTP请求获取网页内容。 2. 解析HTML页面,可以使用Jsoup等HTML解析库,获取美食店铺的信息,如店名、地址、评分等。 3. 如果需要翻页,可以根据网页URL的规律构造下一页的URL地址,再次发送HTTP请求获取下一页的内容。 4. 将获取到的美食店铺信息保存到数据库或文件中,方便后续分析和使用。 以下是一个简单的Java爬虫框架,供您参考: ``` import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.IOException; public class DianPingCrawler { private static final String BASE_URL = "http://www.dianping.com"; private static final String SEARCH_URL = "http://www.dianping.com/search/category/2/10/g110"; public static void main(String[] args) throws IOException { CloseableHttpClient httpClient = HttpClients.createDefault(); String nextPageUrl = SEARCH_URL; while (nextPageUrl != null) { HttpGet httpGet = new HttpGet(nextPageUrl); httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); CloseableHttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); String html = EntityUtils.toString(httpEntity); Document document = Jsoup.parse(html); Elements shopElements = document.select("div.shop-list li"); for (Element shopElement : shopElements) { String name = shopElement.select("h4 > a").text(); String address = shopElement.select("span.addr").text(); String score = shopElement.select("span.sml-rank-stars").attr("title"); System.out.println("店名:" + name); System.out.println("地址:" + address); System.out.println("评分:" + score); System.out.println("===================================="); } Element nextPageElement = document.select("a.next").first(); nextPageUrl = nextPageElement != null ? BASE_URL + nextPageElement.attr("href") : null; } } } ``` 以上代码会爬取大众点评网美食类别下的所有店铺,并输出店名、地址、评分等信息。如需扩展或修改,可以根据需要进行改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值