自定义爬虫筛选规则

本文介绍了作者在使用现有爬虫框架不顺手后,决定自定义爬虫框架的情况。主要探讨了爬虫通常需要爬取的页面内容,包括正文和标签属性如图片、视频URL及链接的href。接着详细讲解了如何定位页面元素,区分单标签、嵌套标签和双标签,并展示了自定义的标签筛选规则,用于提取特定内容。
摘要由CSDN通过智能技术生成

最近迷上了爬虫 在网上找了几个框架 发现用起来都不是特别舒服 在页面筛选元素时 要么只能使用正则 要么就是操作DOM树,还有使用Xpath作为页面元素提取的, 一些其他的设置用起来也不是很顺手因此打算自己编写一个简单的爬虫框架, 方便将来使用

本篇只有页面元素选择的代码

首先分析 我们平时使用爬虫的时候一般爬取的页面内容包括什么

一. 内容
就是正文:开始标签和结束标签中间的文字

二. 标签的属性(图片,视频的URL, 链接)
img 的src 的值
视频的src的值
a标签的href属性

其次就是定位了

定位主要通过标签进行定位, 而标签主要分为三类 单标签 (img, link等), 嵌套标签(div 和span) ,双标签

针对不同标签需设置不同的字符串截取规则

以下是我自定义的一套标签筛选规则可以通过自定义的字符串截取指定的内容主要

通过使用自定义的截取字符串 进行页面元素的筛选
格式为
标签>定位
标签>属性>定位

测试使用
打开csdn
在这里插入图片描述

截取所有的a标签的href属性

在这里插入图片描述

试个复杂的
查看页面代码
在这里插入图片描述

在这里插入图片描述

页面筛选代码如下:

package com.tpddy.spider.utils;

import cn.hutool.core.util.StrUtil;
import lombok.Getter;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author GEP
 * @DESCRIPTION 文本区分器
 * @create 2019/8/14 0014
 */
public class HtmlTextDistinct {
   


    private static final String[] divs = {
   "div", "span"};
    private static final String[] one = {
   "link", "br", "hr", "img", "input", "param", "meta", "link"};

    private static final List<String> oneTitle = new ArrayList<>();
    private static final List<String> nesteTitle = new ArrayList<>();

    static {
   
        oneTitle.addAll(Arrays.asList(one));
        nesteTitle.addAll(Arrays.asList(divs));
    }


    private static String getSimple(String source) {
   
        return source
                // 去除空格
                .replaceAll(" +", "")
                // 去除特殊符号
                .replaceAll("\r+", "")
                .replaceAll("\t+", "")
                .replaceAll("\n+", "")
                // 去除注释
                .replaceAll("<!--(.*?)-->+", "");
    }


    /**
     * 获取标签的所有内容
     * 从标签的起始位置到标签的结束位置
     *
     * @param source
     * @param tag
     * @return
     */
    public static List<String> getDataByTag(String source, String tag) {
   
        source = getSimple(source);
        // 单标签返回结束
        if (isTag(tag, oneTitle)) {
   
            return getOneTagData(source, tag);
            // 嵌套标签
        } else if (isTag(tag, nesteTitle)) {
   
            return getNesteTagData(source, tag);
            // 普通标签
        } else {
   
            return getSimpleTagData(source, tag);
        }
    }


    /**
     * 获取数据
     * @param source
     * @param tag
     * @return
     */
    public List<String> getHtmlData(String source, String tag){
   
        return getData(getSimple(source), tag);
    }

    /**
     * 获取数据
     *
     * @param source
     * @param reTag
     * @return
     */
    public List<String> getData(String source, String reTag) {
   
        Tag tag = new Tag(reTag);
        String nextElement = tag.getNextElement();
        String[] elemetntTags = nextElement.split(">");
        if (elemetntTags.length == 2) {
   
            List<String> dataByTag = getDataByTag(source, elemetntTags[0]);
            List<String> dataByFilter = getDataByFilter(dataByTag, elemetntTags[1]);
            if (tag.hasNextElement()) {
   
                List<String> result = new ArrayList<>();
                for (String s : dataByFilter) {
   
                    result.addAll(getData(s, tag.getSource()));
                }
                return result;
            } else {
   
                return dataByFilter.stream().map(HtmlTextDistinct::getDataRemoveTag).collect(Collectors.toList());
            }
        } else if (elemetntTags.length == 3) {
   
            List<String> dataByTag = getDataByTag(source, elemetntTags[0]);
            List<String> prop = dataByTag.stream().map(data -> getDataByProp(data, elemetntTags[1])).filter(StrUtil::isNotBlank).collect(Collectors.toList());
            return getDataByFilter(prop, elemetntTags[2]);
        } else {
   
            return getDataByTag(source, reTag).stream().map(HtmlTextDistinct::getDataRemoveTag).collect(Collectors.toList());
        }
    }


    /**
     * 根据定位标签进行筛选
     *
     * @param list
     * @param filterStr
     * @return
     */
    public static List<String> getDataByFilter(List<String> list, String filterStr) {
   
        List<String> result = new ArrayList();
        // * 标识全部截取
        if ("*".equals(filterStr)) {
   
            return list;
        }
        Set<Integer> indexSet = new HashSet<>(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值