スクレイピング:Webページからhrefの中に指定した文字が含まれる記事を抜き出し、その記事から必要なデータを抽出する

Pocket

指定したサイトから一昨日の日付を<a href>のリンクに持つ記事をピックアップし、その記事の中からメールアドレスとメール件名を抽出する pythonをChatGPT code interpreterの手も借りながら作成しましたので記録として残しておきます。

1.作成したpythonコード

最終的に作成したpythonコードは以下のとおりです。

# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
import requests
import re
from bs4 import BeautifulSoup

# Set the day before yesterday's date
beforeyesterday = datetime.now() - timedelta(days=2)
beforeyesterday_str = beforeyesterday.strftime("%Y%m%d")
# mail_line_pattern = "From: \"[a-zA-Z0-9_.+-]+.+[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+\""
mail_line_pattern = "From:"
mail_pattern = "^[0-9a-zA-Z_.+-]+@[0-9a-zA-Z-]+\.[0-9a-zA-Z-.]+$"
env_mail_pattern = "<+[0-9a-zA-Z_.+-]+@[0-9a-zA-Z-]+\.[0-9a-zA-Z-.]+>"
subject_line_pattern = "Subject:"

# Initialize an empty list to store the articles
articles_beforeyesterday = []
text_beforeyesterday = []
link_beforeyesterday = []
mail_list = []
email_list = []
env_email_list = []
subject_list = []
title_list = []

# URL of the top page
url = "https://www.xxx.jp/news/"・・・スクレイピングするサイトのURL

# Get the HTML content of the top page
response = requests.get(url)
html = response.content.decode("utf-8")

# Use BeautifulSoup to parse the HTML content
soup = BeautifulSoup(html, "html.parser")

# Find all <a href> elements in the HTML
for a in soup.find_all("a",href=re.compile(beforeyesterday_str)):
    if a in articles_beforeyesterday:
        print("duplicated")
    else:
        text=a.getText()
        link=a.get("href")
        articles_beforeyesterday.append(a)
        text_beforeyesterday.append(text)
        link_beforeyesterday.append(link)

print(articles_beforeyesterday)

for link in link_beforeyesterday:
    # Get the HTML content of the top page
    response = requests.get(link)
    html = response.content.decode("utf-8")

    # Use BeautifulSoup to parse the HTML content
    soup = BeautifulSoup(html, "html.parser")
    print(link)
    mail_list=soup.find_all(string=re.compile(mail_line_pattern))
    
    for mail in mail_list:
        # email = re.findall(mail_line_pattern, mail.replace('\n', ''))
        # ヘッダーメールアドレスが日本語の場合もあるので、以下に修正
        # lstrip()・・・左端の文字(\n)を削除
    # strip(mail_line_pattern)・・・"From:"を削除
        # split('<')[0]・・・"<"以降を削除
        # replace('"', '')・・・ダブルクォーテーションを削除
        email = mail.lstrip().strip(mail_line_pattern).split('<')[0].replace('"', '')
        env_email = re.findall(env_mail_pattern, mail.replace('\n', ''))
        email_list.append(email)
        env_email_list.append(env_email)
    print(email_list)
    print(env_email_list)

    subject_list=soup.find_all(string=re.compile(subject_line_pattern))
    for title in subject_list:
        email_title_line = title.replace('\n', '')
        email_title = email_title_line.replace('Subject: ', '')
        title_list.append(email_title)
    print(title_list)

    # 配列の初期化
    mail_list = []
    email_list = []
    env_email_list = []
    subject_list = []
    title_list = []

2.pythonコード解説

指定した文字列が含まれるhref のリンクをピックアップ

38行目:for a in soup.find_all(“a”,href=re.compile(beforeyesterday_str)):
ここで、reライブラリを利用し一昨日の日付が href のリンクの中に含まれているものを抜き出しています。

指定した文字列で始まる行をピックアップ

59行目:mail_list=soup.find_all(string=re.compile(mail_line_pattern))
では、タグを指定せず、soup に取り込まれた HTMLページからmail_line_patternの正規表現に合致するものを抜き出しています。

文字列からいろいろ削除する

67行目:email = mail.lstrip().strip(mail_line_pattern).split(‘<‘)[0].replace(‘”‘, ”)
コメントも書いていますが、元々の文字列からいろいろな方法でデータを削除し、必要なものだけにしています。

3.実行結果

なお、この時の実行結果は以下の通りです。

% python3 scraping.py
python3 info-tech-center.py
duplicated
[<a href="https://www.xxx.jp/news/20230621xxxxxx.html">○○メールに関する注意喚起a</a>]
https://www.xxx.jp/news/20230621xxxxxx.html
[['From: "xx.xxx.ac.jp"'], ['From: "xx.xxx.ac.jp"'], ['From: "Postmaster@xx.xxx.ac.jp"']]
[['<xxxx-xxxxxxxx@xxx.xxxxxxx.ne.jp>'], ['<xxx@xxxxxxxxxxx.co.jp>'], ['<xxxx@xx.uec.ac.jp>']]
['xxxx@xx.uec.ac.jp 電子メール通知', 'メール認証 xxxx@xx.uec.ac.jp', 'メールボックスのストレージがいっぱいです。アカウントは停止されています。確認が要求されました']

<参考サイト>

・PythonとBeautiful Soupでスクレイピング(Qiita)(https://qiita.com/itkr/items/513318a9b5b92bd56185)
・Python配列のループ処理(Qiita)(https://qiita.com/motoki1990/items/d06fc7559546a8471392)
・図解!Python BeautifulSoupの使い方を徹底解説!(select、find、find_all、インストール、スクレイピングなど)(https://ai-inter1.com/beautifulsoup_1/#st-toc-h-19)
・Pythonで文字列を抽出(位置・文字数、正規表現)(note.nkmk.me)(https://note.nkmk.me/python-str-extract/#_12)
・サルにも分かる正規表現入門(https://userweb.mnet.ne.jp/nakama/)
・Pythonで特定の文字以降を削除する(インストラクターのネタ帳)(https://www.relief.jp/docs/python-get-string-before-specific-character.html)
・【Python】文字列を「〜で始まる/終わる/〜が含まれる」で抽出する方法(てっくらぶ)(https://www.tecrab.com/articles/python-starts-ends-with-in.html)
・[Python コピペ] 文字列内のダブルクォーテーション(”)、シングルクォーテーション(’)の削除方法(資産運用を考えるブログ)(https://kabu-publisher.net/index.php/2021/10/31/16/python_double_single1/)


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA