就活サイトからESをかっさらってくる。
最近、機械学習用の言語データがないかなーって探していたんですけど、いい情報がなくて諦めていました。 そしたらたまたま、いい記事を見つけたので真似をしてみることに。
それがこちらの記事 この記事はunistyleに公開されているESをスクレイピングによって取得するというものでした。
しかし、この記事は2年前に執筆されており、実行すると不具合が出ました。 そこで、コードを修正(コードの可読性、効率は悪くなった、、、)し、ここに記録として載せました。
それが以下のコード
#coding:utf-8 PURPLE = '\033[35m' RED = '\033[31m' CYAN = '\033[36m' OKBLUE = '\033[94m' OKGREEN = '\033[92m' WARNING = '\033[93m' FAIL = '\033[91m' ENDC = '\033[0m' from selenium import webdriver from selenium.webdriver.chrome.options import Options import time from bs4 import BeautifulSoup from extractcontent3 import ExtractContent import pickle import sys ##### ExtractContent(only fetch contents)######## def extractor(html): extractor = ExtractContent() opt = {"threshold":50} extractor.analyse(html) text, title = extractor.as_text() return text email = 'USER_ID' password = 'USER_PASSWORD' LOGIN_URL= 'https://unistyleinc.com/' # Log in options = Options() options.binary_location = "/usr/bin/google-chrome" b = webdriver.Chrome(chrome_options = options, executable_path='./chromedriver') b.get(LOGIN_URL) b.find_element_by_id('LoginLink').click() b.find_element_by_name('user[email]').send_keys(email) b.find_element_by_name('user[password]').send_keys(password) b.find_element_by_class_name('login_submit').click() def first(): # Move to categories time.sleep(0.1) b.get('https://unistyleinc.com/categories') category = b.find_element_by_class_name('es_category_list') a = category.find_elements_by_css_selector("a") dict_category = {} for total,i in enumerate(a): if not total == int(category_num): continue name = str(i.text.replace('>','')) URL = str(i.get_attribute("href")) print ('STEP1 : '+str(total+1)+'/'+str(len(a))+' '+name+'--->'+OKBLUE+URL+ENDC) dict_category[name]=URL # Move to company from the category dict_company = {} for name in dict_category: URL = dict_category[name] b.get(URL) time.sleep(0.1) companies = b.find_element_by_class_name('essearch_common_wrap') a = companies.find_elements_by_css_selector("a") for i in a: company = str(i.text.split(' ')[0]) URL = str(i.get_attribute("href")) if URL != 'https://unistyleinc.com/categories': dict_company[company] = URL print ('STEP2 : '+company+'--->'+OKGREEN+URL+ENDC) # 本選考などESpageを取得 dict_kindofES = {} for company in dict_company: URL = dict_company[company] b.get(URL) time.sleep(0.1) ESs = b.find_element_by_class_name('essearch_common_wrap') a = ESs.find_elements_by_css_selector("a") count = 0 for i in a: cmp = str(i.text.split(' ')[0]) URL = str(i.get_attribute("href")) if count != 0 and URL != 'https://unistyleinc.com/categories': dict_kindofES[company+cmp] = URL print ('STEP3 : '+company+cmp+'--->'+OKGREEN+URL+ENDC) count = count + 1 # Move to (ES/interview/OB visit etc...)page from company URL dict_com_url = {} for company in dict_kindofES: URL = dict_kindofES[company] b.get(URL) def get_ES_URL(b,dict_com_url): time.sleep(0.1) list_ES = b.find_elements_by_class_name('es_container') for i in list_ES: a = i.find_element_by_css_selector("a") url = str(a.get_attribute("href")) print ('STEP4 : '+company+'--->'+PURPLE+url+ENDC) dict_com_url.setdefault(company, []).append(url) ES_page_number = b.find_elements_by_class_name('fg essearch_page_btn') if not len(ES_page_number) == 0: for epn in ES_page_number: a = epn.find_element_by_css_selector("a") EsPageUrl = str(a.get_attribute("href")) b.get(EsPageUrl) get_ES_URL(b,dict_com_url) else: get_ES_URL(b,dict_com_url) with open('./dict_com_url.pickle', mode='wb') as f: pickle.dump(dict_com_url,f) def second(): with open('./dict_com_url.pickle', mode='rb') as f: dict_com_url = pickle.load(f) #Save contents W = open('result'+args[2]+'.csv','w') W.write('ID,Company,URL,Contents\n') num = 0 code = 0 dict_com_url_count = 0 for key in dict_com_url: list_URL = dict_com_url[key] for j,URL in enumerate(list_URL): try: b.get(URL) time.sleep(0.1) html = b.page_source text = extractor(html) # text = text.replace(',','').replace('\n',' ').replace('\t','').replace('\r','') text = text.replace(',',',') print ('STEP5 : '+key+'--->'+PURPLE+URL+ENDC) print (text[:100]+'...') W.write(str(num)+','+key+','+URL+','+text+'\n') except: # print ('request error') code = 1 break num+=1 if code == 1: print("システムが終了しました。\n最終実行はdic_com_url:"+str(dict_com_url_count)+"番のlist_URL:"+str(j)+"番です。") break dict_com_url_count += 1 W.close() def therd(): with open('./dict_com_url.pickle', mode='rb') as f: dict_com_url = pickle.load(f) #Save contents W = open('result'+args[2]+'.csv','a') num = int(args[3]) code = 0 dict_com_url_count = 0 for i,key in enumerate(dict_com_url): if i >= int(args[3]): list_URL = dict_com_url[key] for j,URL in enumerate(list_URL): if i == int(args[3]) and j < int(args[4]): continue try: b.get(URL) time.sleep(0.1) html = b.page_source text = extractor(html) text = text.replace(',',',') print ('STEP5 : '+key+'--->'+PURPLE+URL+ENDC) print (text[:100]+'...') W.write(str(num)+','+key+','+URL+','+text+'\n') except: code = 1 break num+=1 if code == 1: print("システムが終了しました。\n最終実行はdic_com_url:"+str(dict_com_url_count)+"番のlist_URL:"+str(j)+"番です。") break dict_com_url_count += 1 W.close() args = sys.argv category_num = args[2] if args[1] == "1": first() elif args[1] == "2": second() elif args[1] == "3": therd() else: print(args+"が入力されました\n第一引数:シーケンス番号,第二引数:カテゴリ番号,第三引数:中途開始番号1,第四引数:中途開始番号2")
このコードは2回、ないし3回実行することが必要です。
実行は
python3 Scraping.py 1 [企業カテゴリ番号(0-35)] python3 Scraping.py 2 [企業カテゴリ番号(0-35)]
しかし、seleniumの影響でスクレイピング数が変化します。 なので、もし途中で止まった場合、どこで止まったか最後に表示するようにしているので、 その続きから実行するために
python3 Scraping.py 3 [企業カテゴリ番号(0-35)] [中途開始番号1] [中途開始番号2]
として、エラーなく最後まで実行できるようにします。 また、これでもまだ途中で止まる可能性があるので、その場合は途中開始番号1に前回の途中開始番号1を足した値を入れてあげることで またその続きから実行できます。
お粗末な改修プログラムですが、誰かのお役にたてますように