PHP笔记网

革命尚未成功,同志仍须努力下载JDK17

作者:Albert.Wen  添加时间:2022-06-08 09:01:47  修改时间:2024-11-25 06:30:12  分类:03.数据采集/爬虫  编辑

项目中,需要用爬虫去抓取页面数据,然后解析出其中的联系方式,如:“邮箱”和“电话号码”,刚开始,大伙潜意识地想到直接用正则表达式去提取,网上也有很多现成的“邮箱”和“电话号码”的正则表达式。代码跑了一段时间后,发现抓取到的“邮箱”数据到是挺正常,而“电话号码”的书写方式却千奇百怪,先前找到的正则就不那么灵敏,总而言之,解析出来的“电话号码”一看就很假,销售人员打过去,肯定也报空号。

把采集过来的“原始数据”仔细分析了一下,其实还是有个小规律的,他们往往会在“电话号码”前加一个前缀,如:TelefonTelPhone numberMobiltel,我们可以从它们出现的地方入手,然后一直逐个字符地匹配,直到遇到“电话号码”中不可能出现的字符时,就停止收集字符,这样就可以把这个“电话号码”大概率地正确地收集到

整理出的代码如下:

(1) 助手类

package com.wanma.framework_noweb.helper;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 爬虫 助手类
 */
public class SpiderHelper {
    /**
     * 手机号前缀
     * 【注意】
     * (1)不区分大小写
     * (2)不要添加冒号:
     */
    private static final String[] phoneNumberPrefixArr = {
            "Telefon",
            "Tel",
            "Tel.",
            "Phone number",
            "Mobiltel"
    };

    /**
     * 获取手机号 列表
     *
     * @param html HTML文本字符串
     * @return 返回列表
     */
    public static List<String> getPhoneNumberList(String html) {
        //content = """
        //         Bahnhofsplatz 3<br>
        //          77694 Kehl<br>
        //          Telefon: 07851 / 991480<br>
        //          <p>张三</p>
        //          telefon :  0795 - 781493ABC<br>
        //          <p>李四</p>
        //          telefon :  +86 0795 - 781493<br>
        //          <p>王二</p>
        //          telefon   (0795) 781493<br>
        //          telefon(0794)493781<br>
        //        """;

        List<String> phoneNumbers = new ArrayList<>();
        
        if (StrUtil.isEmpty(html)) {
            return phoneNumbers;
        }
        
        // 去掉 HTML标签、换行符
        html = HtmlUtil.cleanHtmlTag(html).replaceAll("\r", "").replaceAll("\n", "");
        //System.out.println(html);
        
        for (String phoneNumberPrefix : phoneNumberPrefixArr) {
            String phoneNumberReg = phoneNumberPrefix + "\s*:?\s*([0-9\s\\-+/()–]+)";
            Pattern pattern = Pattern.compile(phoneNumberReg, Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(html);
            while (matcher.find()) {
                // 电话号码/手机号
                String phoneNumber = matcher.group(1).trim();
                if (StrUtil.isEmpty(phoneNumber)) {
                    continue;
                }
                // 去掉尾部无效字符
                phoneNumber = phoneNumber.replaceFirst("[\s\\-+/()–]+$", "");
                
                // 至少要包含数字
                if (!Pattern.compile("[0-9]+").matcher(phoneNumber).find()) {
                    continue;
                }
                phoneNumbers.add(phoneNumber);
            }
        }

        if (ObjectUtil.isEmpty(phoneNumbers)) {
            return phoneNumbers;
        }

        return phoneNumbers.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 获取手机号 字符串
     * 多个值以","分隔
     *
     * @param html HTML文本字符串
     * @param sep  分隔符
     * @return 返回字符串
     */
    public static String getPhoneNumberStr(String html, String sep) {
        List<String> phoneNumberList = getPhoneNumberList(html);
        return CollectionUtil.join(phoneNumberList, sep);
    }

    public static String getPhoneNumberStr(String html) {
        return getPhoneNumberStr(html, ",");
    }
}

(2) 使用示例

package com.wanma;

import com.wanma.framework_noweb.helper.SpiderHelper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class RunTest {

    @Test
    void test01() {
        String html = """
                  <div id="about-seller-section" class="a-section expandable-text-section">
                              <span class="expandable-text">
                                  <span id="about-seller-truncated" class="expandable-truncated-text" style="display: none;"><p><strong>Impressum</strong><br> Verantwortlich im Sinne des § 5 TMG: Dani´s Kosmetikshop Inhaberin: Daniela Huber</p> <p>&nbsp; </p><p><strong>Adresse</strong><br> Daniela Huber<br> Eichendorffstraße 7<br> 84494 Neumarkt-Sankt Veit<br> Deutschland<br> Telefon 0176 23885354</p> <p><strong>Ansprechpartner</strong><br> Daniela Huber</p> <p><strong>Steueridentifikation</strong><br> Steuer Nummer 141/231/41238<br> USt-IdNr. DE325996567</p> <p><strong>Haftung fuer Inhalte</strong><br>Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Fuer die Richtigkeit, Vollständigkeit und Aktualität der Inhalte können wir jedoch keine Gewähr übernehmen. Als Diens...</p></span>
                                  <span id="about-seller-expanded" class="expandable-expanded-text" style="display: inline;"><p><strong>Impressum</strong><br>
                  Verantwortlich im Sinne des § 5 TMG: Dani´s Kosmetikshop Inhaberin: Daniela Huber</p>
                  
                  <p>&nbsp;
                  </p><p><strong>Adresse</strong><br>
                  Daniela Huber<br>
                  Eichendorffstraße 7<br>
                  84494 Neumarkt-Sankt Veit<br>
                  Deutschland<br>
                  Telefon 0176 23885354</p>
                  
                  
                  <p><strong>Ansprechpartner</strong><br>
                  Daniela Huber</p>
                  
                  <p><strong>Steueridentifikation</strong><br>
                  Steuer Nummer 141/231/41238<br>
                  USt-IdNr. DE325996567</p>
                  
                  <p><strong>Haftung fuer Inhalte</strong><br>
                  Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Fuer die Richtigkeit, Vollständigkeit und Aktualität der Inhalte können wir jedoch keine Gewähr übernehmen. Als Diensteanbieter sind wir gemäfl $ 7 Abs.1 TMG fuer eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.</p>
                  
                  <p>Haftung fuer Links</p>
                  
                  <p>Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir fuer diese fremden Inhalte auch keine Gewähr uebernehmen. Fuer die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.</p>
                  
                  <p></p>
                  
                  <p>Wir nehmen nicht an einem Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teil. Das Gesetzes über die alternative Streitbeilegung in Verbrauchersachen fordert aber, dass wir Sie trotzdem auf eine für Sie zuständige Verbraucherschlichtungsstelle hinweisen:</p>
                  
                  <p>Online-Schlichter<br>
                  Zentrum für Europäischen Verbraucherschutz e.V.<br>
                  Bahnhofsplatz 3<br>
                  77694 Kehl<br>
                  Telefon: 07851 / 991480<br>
                  E-Mail:&nbsp;mail@online-schlichter.de<br>
                  Internet:&nbsp; online-schlichter.de</p>
                  <!--~~ BEGIN odr ~~--><p></p><p>Die Europäische Kommission bietet eine Onlineplattform für Streitbeilegung an, die Sie hier finden: <a class="a-link-normal" target="_blank" rel="noopener" href="https://ec.europa.eu/consumers/odr/">https://ec.europa.eu/consumers/odr/</a></p><p></p><!--~~ END odr ~~--><!--~~ BEGIN adr ~~--><p></p><p>Unter diesem Link finden Sie die Kontaktdaten der offiziellen Streitbeilegungsstellen: <a class="a-link-normal" target="_blank" rel="noopener" href="https://webgate.ec.europa.eu/odr/main/index.cfm?event=main.adr.show">https://webgate.ec.europa.eu/odr/main/index.cfm?event=main.adr.show</a></p><p></p><!--~~ END adr ~~--></span>
                              </span>
                              <span class="expandable-action expandable-expand-action" style="display: none;">
                                  <span class="a-declarative" data-action="expand-text" data-csa-c-type="widget" data-csa-c-func-deps="aui-da-expand-text" data-expand-text="{}" data-csa-c-id="gfhnjc-wgya80-hqbdy8-mrr1sx">
                                      <a id="about-seller-expand" aria-label="Click to read more" class="a-size-small a-link-normal" href="#">
                                          Read more
                                      </a>
                                  </span>
                              </span>
                              <span class="expandable-action expandable-reduce-action" style="display: inline;">
                                  <span class="a-declarative" data-action="reduce-text" data-csa-c-type="widget" data-csa-c-func-deps="aui-da-reduce-text" data-reduce-text="{}" data-csa-c-id="er44hf-8hot8s-x9z29y-k3rmm9">
                                      <a id="about-seller-reduce" aria-label="Click to read less" class="a-size-small a-link-normal" href="#">
                                          Read less
                                      </a>
                                  </span>
                              </span>
                          </div>
                """;

        html = """
                 Bahnhofsplatz 3<br>
                  77694 Kehl<br>
                  Telefon: 07851 / 991480<br>
                  <p>张三</p>
                  telefon :  0795 - 781493ABC<br>
                  <p>李四</p>
                  telefon :  +86 0795 - 781493<br>
                  <p>王二</p>
                  telefon   (0795) 781493<br>
                  telefon(0794)493781<br>
                """;
        List<String> phoneNumberList = SpiderHelper.getPhoneNumberList(html);
        String phoneNnumberStr = SpiderHelper.getPhoneNumberStr(html);
        
        System.out.println(phoneNumberList);
        System.out.println(phoneNnumberStr);
    }
}

输出:

[07851 / 991480, 0795 - 781493, +86 0795 - 781493, (0795) 781493, (0794)493781]
07851 / 991480,0795 - 781493,+86 0795 - 781493,(0795) 781493,(0794)493781