python/selenium/bs4でハローワークの求人情報を取得してメールしてみる

Python

今回も前回のTwitter自動投稿機能に続いて、seleniumを使ったスクレイピングとメール送信の機能を実装してみました。

準備するもの

  • pip環境
  • selenium(pipにinstall、chrome自動操作用)
  • bs4(pipにinstall、ハローワークのページデータ解析用)
  • smtplib(pipにinstall、メール送信用)
  • gmailアドレス+google appパスワード
  • python3

python/selenium etcで実装すること

  1. seleniumを使って、ハローワーク(https://www.hellowork.go.jp/index.html)の求人情報サービスから欲しい情報を抽出
  2. bs4を利用して、ページを解析して必要データを抽出
  3. smtplibを利用して、gmailアドレスからメールを送る
  4. cron/launchdで自動実行を設定

抽出してメールした結果イメージ

自動送付メール

検索結果1ページ目に最新案件から表示されるので、とりあえず1ページ目だけseleniumで表示させて、データを加工してメールを送るようにしています。元となるデータは以下のようなページになっています(link: https://www.hellowork.go.jp/servicef/130050.do)。

ハローワーク求人検索情報

実際のコード

#selenium スクレイピング関係
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.expected_conditions import visibility_of
import chromedriver_binary
import bs4,requests,time,os,sys,random,re,csv

#メール送信関係
import smtplib
from email.mime.text import MIMEText
from email.header import Header

driver = webdriver.Chrome()
url = 'https://www.hellowork.go.jp/index.html' #seleniumをスタートするurl
Base_url = "https://www.hellowork.go.jp/servicef/" #メール送付時にデータ抽出用の基礎とするurl

from_adress = "XXX@gmail.com" #送付もとメールアドレス、gmailを前提
from_adress_pass = "XXXXXXXXXXXX" #Google accountから発行される16桁のアプリパスワードに変更(2要素認証)
to_adress = "XXX@XXXXXX" #受信メールアドレス

def get_work_info():

    output_list = []

    driver.get(url)

    driver.find_element_by_class_name('index_search').find_element_by_tag_name('form').click()

    #検索画面へ以降
    driver.find_element_by_xpath('//*[@id="ID_todofuken23"]').click() #愛知
    #driver.find_element_by_xpath('//*[@id="ID_todofuken13"]').click() #tokyo
    #driver.find_element_by_xpath('//*[@id="ID_todofuken14"]').click() #kanagawa
    driver.find_element_by_xpath('//*[@id="ID_hakenUkeoi2"]').click() #ukeoi

    driver.find_element_by_xpath('//input[@value="検索"]').click()

    #求人情報の一覧ページ、詳細検索条件の設定

    html_wait = WebDriverWait(driver, 10)
    #詳細条件全部開く
    driver.find_element_by_xpath('//input[@value="+ 開く"]').click()
    #<input type="button" id="ID_allOpen1" name="allOpen1" class="submit01 float-left dynaBtn btn04" tabindex="0" onclick="exMenuAllOpen('kyushokuUmu','kyujinJigyosho','shugyoBasho','shigotoNaiyo','oboJoken','rodoJoken','fukuriKosei','freeWord',1)" value="+ 開く">
    #希望職種設定
    elm = driver.find_element_by_xpath('//*[@id="ID_kiboShokushu1"]')
    elm.send_keys(10)
    driver.find_element_by_xpath('//input[@value="検索"]').click()

    pars_page = bs4.BeautifulSoup(driver.page_source, "lxml")
    # job_new = pars_page.select(".sole-small > tbody > tr > td > div") ##ID_mainForm > div:nth-child(27) > div.d-sole > table > tbody > tr:nth-child(2) > td:nth-child(1) > div

    job_link = pars_page.select(".sole-small > tbody > tr > td > a")
    job_content = pars_page.select(".left > div")

    for i in range(len(job_content)):
        if i % 6 == 0: #left要素が6個あるため
            num = i / 6
            raw_url = job_link[int(num)].get("href")
            edited_url = re.sub(r"^\./", "", raw_url)
            combined_url = Base_url + edited_url
            print("\n" + combined_url)
            output_list.append(combined_url)
        output_list.append(job_content[i].text)


    return output_list

def send_email(data):

    string = ""

    for i in range(len(data)):
        string = string + str(data[i]) + "\n"
        if (i + 1) % 7 == 0:
            string = string + "\n"
    string = string + "\n"

    msg = MIMEText("求人情報通知。\n\n" + string, "plain")
    msg["Subject"] = Header("from_bot ハロワ求人情報")

    smtp_obj = smtplib.SMTP("smtp.gmail.com", 587)
    smtp_obj.ehlo()

    smtp_obj.starttls()

    smtp_obj.login(from_adress, from_adress_pass)
    smtp_obj.sendmail(from_adress, to_adress, msg.as_string())
    smtp_obj.quit()

    return True


if __name__ == "__main__":
    try:
        send_email(get_work_info())
        driver.close()

    except KeyboardInterrupt:
        print("\nprogram was ended.\n")
        sys.exit()

まとめ

ハローワークは実はAPIも提供しているのですが、OpenAPIではなく、有料職業紹介事業者だけが利用できるAPIとなっています。そのため、スクレイピングでデータを集めてくるのが一般ユーザとしてはベストになっています。ちなみにAPIもresponseはxmlなので、なんでJSONじゃないんだ。。。というクレームはありますが。。

自分の興味ある地域・職種のデータを取得してみてみると楽しいかもしれません。WantedlyやBizreachに出てくる募集内容とはまた違った、昔ながらの募集をみてみるのも差がどこにあるのかみたりするのが個人的には勉強になります(法的対応とかそうい問題ではなく、募集内容自体についてですが)。

自動化で空き時間を作り、日頃時間が取れない要素の検証とかするのが、プログラミングのメリットでもありますし、ぜひお試しください。

コードで不明点がありましたら、お問い合わせかコメントバックいただければと思います。

コメント