<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>英語 - イチゾーのブログ</title>
	<atom:link href="https://ichizo.biz/category/%E8%8B%B1%E8%AA%9E/feed" rel="self" type="application/rss+xml" />
	<link>https://ichizo.biz</link>
	<description>システム開発やWordPressについてなど</description>
	<lastBuildDate>Thu, 29 Dec 2016 08:29:30 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>
<site xmlns="com-wordpress:feed-additions:1">120380898</site>	<item>
		<title>PythonでAmazon Product Advertising APIを呼び出してKindle Unlimitedの情報を取得する</title>
		<link>https://ichizo.biz/2016/12/29/kindle-unlimited.html</link>
					<comments>https://ichizo.biz/2016/12/29/kindle-unlimited.html?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[一蔵]]></dc:creator>
		<pubDate>Thu, 29 Dec 2016 08:25:19 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[英語]]></category>
		<category><![CDATA[Amazon Product Advertising API]]></category>
		<category><![CDATA[英語多読]]></category>
		<guid isPermaLink="false">http://ichizo.biz/?p=100</guid>

					<description><![CDATA[<p>「英語多読用の本をレベル別に取得する（完成版）」で、 英語多 [&#8230;]</p>
<p>The post <a href="https://ichizo.biz/2016/12/29/kindle-unlimited.html">PythonでAmazon Product Advertising APIを呼び出してKindle Unlimitedの情報を取得する</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>「<a href="http://ichizo.biz/2016/12/29/python-selenium-3.html">英語多読用の本をレベル別に取得する（完成版）</a>」で、<br />
英語多読用の本のISBNリストを取得しました。</p>
<p>今度はこれを使用して、Amazon Product Advertising APIを呼び出してKindle Unlimitedの情報を取得するということをやります。</p>
<h2>目的：英語多読をKindle Unlimitedでやりたい</h2>
<p>英語力を伸ばしたいということで、英語多読をやってみたいのですが、<br />
多読用の本を買っていては高くついてしまうというネックがあります。</p>
<p><a href="https://www.seg.co.jp/sss/learning/sss-for-low-intermeidate.html" target="_blank">英語多読研究会さんのHP</a>に、難易度別の類型読書語数の目安が掲載されています。</p>
<p>それによると、各レベルごとの累計語数は以下のようになっています。</p>
<pre>
Level0　　 30,000語
Level1　　120,000語
Level2　　470,000語
Level3　1,020,000語
Level4　1,320,000語
Level5　1,600,000語
Level6　1,900,000語
Level7　2,000,000語
Level8　2,200,000語
Level9　2,380,000語
</pre>
<p>これを達成するためには、各レベルで以下の冊数が必要になります。</p>
<pre>
Level0　30冊
Level1　30冊
Level2　50冊
Level3　50冊
Level4　15冊
Level5　10冊
Level6　10冊
Level7　2冊
Level8　2冊
Level9　1冊
</pre>
<p>Level0では、3万語の読書語数が推奨されていますが、<br />
これを満たすためには大体30冊読まなければいけないという計算になります。</p>
<p>Level9では、読書語数は18万語となっていますが、<br />
読むべき冊数は1冊です。</p>
<p>これは、難易度があがると1冊あたりの語数が増えるため、<br />
読む必要がある冊数は減ってくるということですね。</p>
<p>英語多読を始めたばかりの難易度の低い頃に読むのが<br />
語数が少なく読みやすい本（児童向けだったりします）になりますので、<br />
必然的に読むべき冊数が増えてしまいます。</p>
<p>１冊あたり500円とか600円とかなので、決して高いわけではありませんが、<br />
Level0で30冊、Level1で30冊、Level2で50冊・・・<br />
となると、一人で揃えるには予算的に非常に厳しいものがあります。</p>
<p>そこで、読み放題のKindle Unlimitedを英語多読に使えないかと考えた訳です。</p>
<p>英語多読研究会さんでは、<a href="http://www.seg.co.jp/sss_review/jsp/frm_a_100.jsp" target="_blank">多読用の洋書のリストを難易度別に公開されています</a>ので、<br />
ここで公開されている本のリストから、Kindle Unlimitedに登録されているものを探し出すということをやってみます。</p>
<p>多読用の本のリスト取得は<a href="http://ichizo.biz/2016/12/29/python-selenium-3.html">前回</a>までに行っていますので、<br />
今回は取得したリストを元にAmazon Product Advertising APIを呼び出して本の情報を取得するということをやってみます。</p>
<p>ソースコード</p>
<pre class="lang:python decode:true " title="amazon_api.py" >
# -*- coding: utf-8 -*-
"""
Created on Mon Dec 19 14:49:19 2016

@author: 
"""

from bottlenose import api
from lxml import objectify
import time

AMAZON_ACCESS_KEY_ID = "アクセスキー"
AMAZON_SECRET_KEY = "シークレットキー"
AMAZON_ASSOC_TAG = "アソシエイトタグ"

KINDLE_UMLIMITED_NODE_ID = "4486610051"

amazon = api.Amazon(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, Region = "JP")

def file_read (file):
    f = open(file, 'r')
    data = f.read()
    f.close()
    lines = data.split('\n')
    return lines

def loop_min(max_level):
    book_list = []
    min_level = 0
    while min_level &lt; 1:
        level = max_level + min_level
        print('list'+str('%1.1f' % level)+'.txt')
        lines = file_read('list'+str('%1.1f' % level)+'.txt')
        for line in lines:
            if (len(line) &gt; 0):
                print('line='+line)
                items = item_search(line)
                item_find = items.find('Item')
                if (item_find is not None):
                    for item in item_find:
                        if (item is not None):
                            title = item.ItemAttributes.Title
                            author = item.ItemAttributes.Author
                            isbn = item.ItemAttributes.Isbn
                            url = item.DetailPageURL
                            print(("%s, %s, %s, %s, %s" % (line, title, author, isbn, url)))
                            book_list.append(str("%s, %s, %s, %s, %s" % (line, title, author, isbn, url)))
                        else:
                            print ("%s : Book is None" % (line))
                #print ("END %s" % (line))
                time.sleep(5)   # Amazon API呼び出しは1秒に1回以内に収めるためsleep

        min_level += 0.1
        
    return book_list
    
def loop_max():
    max_level = 0
    while max_level &lt; 10:
        book_list = loop_min(max_level)
        write_file(book_list, max_level)
        max_level += 1
    
def write_file(book_list, max_level):
    f = open('amazon'+str('%1d' % max_level)+'.txt', 'w')
    for book in book_list:
        f.write(book)
        f.write('\n')
    f.close()

def item_search (keywords, searchIndex="KindleStore", browseNode=KINDLE_UMLIMITED_NODE_ID):
    response = amazon.ItemSearch(Keywords=keywords, SearchIndex=searchIndex, BrowseNode=browseNode, ResponseGroup="Large")
    root = objectify.fromstring(response)
    return root.Items

if __name__ == '__main__':
    
        loop_max()
</pre>
<p>bottlenoseを使ってAmazon Product Advertising APIを呼び出しています。</p>
<p>この使い方は<a href="http://ichizo.biz/2016/12/20/english-kindle-unlimited.html">以前の記事</a>を参考にしてください。</p>
<p>今回やっていることは、ISBNのリストファイルを開き１行ずつAmazon Product Advertising APIで<br />
Kindle Unlimitedの情報を取得するということです。</p>
<p>ループの頻度ですが、Amazon Product Advertising APIには<br />
頻繁にアクセスするとエラーを返す仕様がある（1秒間に1回以内に抑える）ので<br />
sleepを5秒入れています。</p>
<p>これで実行していたのですが、<br />
「接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。」<br />
というエラーが返ってきて中断しましたので、sleep 10秒で再トライしてみます。</p>
<p>英語多読で使えるKindle Unlimitedの本のリストはまとめて公開したいと思います。</p><p>The post <a href="https://ichizo.biz/2016/12/29/kindle-unlimited.html">PythonでAmazon Product Advertising APIを呼び出してKindle Unlimitedの情報を取得する</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://ichizo.biz/2016/12/29/kindle-unlimited.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">100</post-id>	</item>
		<item>
		<title>英語多読用の本をレベル別に取得する（完成版）</title>
		<link>https://ichizo.biz/2016/12/29/python-selenium-3.html</link>
					<comments>https://ichizo.biz/2016/12/29/python-selenium-3.html?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[一蔵]]></dc:creator>
		<pubDate>Thu, 29 Dec 2016 03:52:31 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[英語]]></category>
		<category><![CDATA[Selenium]]></category>
		<guid isPermaLink="false">http://ichizo.biz/?p=94</guid>

					<description><![CDATA[<p>英語多読用の本をレベル別に取得する（完成版） これまでのまと [&#8230;]</p>
<p>The post <a href="https://ichizo.biz/2016/12/29/python-selenium-3.html">英語多読用の本をレベル別に取得する（完成版）</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2>英語多読用の本をレベル別に取得する（完成版）</h2>
<h3>これまでのまとめと残りの実装</h3>
<p>検索を行いその結果をリスト化しテキストに保存するという一連の作業を実装します。</p>
<p>検索の実行はPythonでSeleniumを動作させて行います。</p>
<p>英語多読研究会さんのWEBページから、読みやすさレベル別に本のリストを取得するスクリプトの完成版です。</p>
<p>これまで、「<a href="http://ichizo.biz/2016/12/27/python_selenium.html">英語多読用の本のリストをレベル別に取得する</a>」や<br />
「<a href="http://ichizo.biz/2016/12/28/python_selenium-2.html">英語多読用の本をレベル別に取得する（ページャーも対応）</a>」で<br />
実装してきたものの完成版です。</p>
<p>レベル別の英語多読用の本のリストをそれぞれテキストファイルに書き出すという処理です。</p>
<p>読みやすさレベルは、0.0から0.1刻みで10.0まであるので、<br />
それぞれのレベルごとに本のリストを取得して、そのISBNをテキストファイルに書き出します。</p>
<p>今までは書名を取得していたのですが、検索結果の中にISBNが含まれていたことに気が付き、これを取得することにしました。</p>
<h3>プログラムソース</h3>
<p>では、プログラムソースです。</p>
<pre class="lang:python decode:true " title="selenium_english.py" >
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 22 16:32:48 2016

@author: 
"""

from selenium import webdriver

url = 'http://www.seg.co.jp/sss_review/jsp/frm_a_100.jsp'
keyword0 = '100'
level_no = 0
isbn_list = []

def open_window():
    try:
        browser = webdriver.Chrome('./chromedriver')
    finally:
        print('END')
    return browser
        
def search_web(browser, keyword1):
    browser.get(url)
    
    search_input = browser.find_element_by_name('dt_page_in')
    search_input.send_keys(keyword0)

    search_input = browser.find_element_by_name('nm_yle')
    search_input.send_keys(keyword1)

    search_input = browser.find_element_by_name('nm_yls')
    search_input.send_keys(keyword1)
    
    browser.find_element_by_name('Submit3022233').click()
    
    return browser

def go_next_page(browser):
    isFind = True
    page_no = 1
    
    while isFind:
        get_isbns(browser)
    
        page_no += 1
        search_word = '"JavaScript:fncPagnig('+str(page_no)+');"'
        
        if browser.page_source.find(search_word) &gt; 0:
            browser.find_element_by_xpath('//a[@href='+search_word+']').click()
        else:
            isFind = False

def get_isbns(browser):
    subjects = browser.find_elements_by_class_name('subj')
    for subject in subjects:
        if subject.text.find('●ISBN：') &gt; 0:
            isbn = subject.text.split('●ISBN：')
            isbn = isbn[1].split('(')
            isbn_list.append(isbn[0])

def write_file(level_no):
    f = open('list'+str('%1.1f' % level_no)+'.txt', 'w')
    for isbn in isbn_list:
        f.write(isbn)
        f.write('\n')
    f.close()
    

if __name__ == '__main__':
    browser = open_window()
    while level_no &lt; 10:
        browser = search_web(browser, str('%1.1f' % level_no))
        go_next_page(browser)
        write_file(level_no)
        level_no += 0.1
        isbn_list = []
</pre>
<h3>プログラムソースの説明</h3>
<p>ソース下部の</p>
<pre class="lang:python decode:true " >if __name__ == '__main__':</pre>
<p>から各メソッドを実行していますので、ここから説明していきます。</p>
<p>これまではsearch_web()内で</p>
<pre class="lang:python decode:true " >browser = webdriver.Chrome('./chromedriver')</pre>
<p>を行っていたのですが、検索のたびに新しいウィンドウを立ち上げたくなかったので、<br />
別途open_window()メソッドを定義して、1回だけこれを呼び出すことにしました。</p>
<p>読みやすさレベルは、0.0から10.0まで検索を続けるので、<br />
whileループで各レベルごとに検索処理を実行します。</p>
<p>ループ内では、search_web()で検索処理を実行し、<br />
検索結果をgo_next_page()に渡します。</p>
<p>go_next_page()では、検索結果ページごとにget_isbns()を呼び出し、<br />
ページャーのリンクを探します。<br />
ページャーのリンクの数だけ、リンクをクリックし、検索結果をget_isbn()に渡すことを繰り返します。</p>
<p>get_isbns()では、ISBNはclass名が「subj」というtdタグで囲まれているので、<br />
find_elements_by_class_nameで「subj」を指定して中の文字列を取得します。<br />
これで文字列はリストに入るので、この文字列でループし、<br />
「●ISBN」という文字列がある場合だけISBNを取得し、これをリストに追加します。</p>
<p>ISBNをリストに追加し終わったらwrite_file()で<br />
読みやすさレベル別にテキストファイルに保存します。</p>
<p>次にlevel_no（読みやすさレベル）を0.1上げて、<br />
検索結果をセットするリストを初期化しておきます。</p>
<p>以上をlevel_noが10になるまで繰り返します。</p>
<p>注意事項</p>
<p>私は、非常に低スペックのパソコンで実行しているためか、<br />
Seleniumで検索を行ってページ送りしてという動作が非常に緩慢です。<br />
手動で検索を行ってページ送りしてというよりも動作が遅いぐらいです。</p>
<p>ですのでsleepを入れていませんが、<br />
高スペックパソコン等で検索やページ送りの動作が非常に速い場合は<br />
ループの間隔をあけるように適度にsleepを入れましょう。</p><p>The post <a href="https://ichizo.biz/2016/12/29/python-selenium-3.html">英語多読用の本をレベル別に取得する（完成版）</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://ichizo.biz/2016/12/29/python-selenium-3.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">94</post-id>	</item>
		<item>
		<title>英語多読用の本をレベル別に取得する（ページャーも対応）</title>
		<link>https://ichizo.biz/2016/12/28/python_selenium-2.html</link>
					<comments>https://ichizo.biz/2016/12/28/python_selenium-2.html?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[一蔵]]></dc:creator>
		<pubDate>Wed, 28 Dec 2016 08:04:19 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[英語]]></category>
		<category><![CDATA[Selenium]]></category>
		<guid isPermaLink="false">http://ichizo.biz/?p=91</guid>

					<description><![CDATA[<p>英語多読用の本をレベル別に取得する（ページャーに対応する）  [&#8230;]</p>
<p>The post <a href="https://ichizo.biz/2016/12/28/python_selenium-2.html">英語多読用の本をレベル別に取得する（ページャーも対応）</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2>英語多読用の本をレベル別に取得する（ページャーに対応する）</h2>
<p>前回の「<a href="http://ichizo.biz/2016/12/27/python_selenium.html">英語多読用の本のリストをレベル別に取得する</a>」に引き続き、<br />
英語多読研究会さんのデータベースから、読みやすさレベル別の書籍リストを取得する実装を行います。</p>
<p>検索結果が多数のページにまたがらないように、結果一覧ページの表示件数を最大の100件にしています。<br />
また読みやすさレベルで細かく分けられるように、検索項目の読みやすさレベルを0.1刻みで上げていく方法を取ります。<br />
他の絞り込み条件を入れると、リストから漏れてしまったりということも考えられなくもないので、<br />
単純に読みやすさレベルを細かく刻むことでその対応とします。</p>
<p>前回の記事で紹介したPythonのソースをさらに書き換えます。</p>
<p>プログラムは以下のようになりました。</p>
<h3>プログラムソース</h3>
<pre class="lang:python decode:true " title="get Book List" >
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 22 16:32:48 2016

@author: 
"""

from selenium import webdriver

url = 'http://www.seg.co.jp/sss_review/jsp/frm_a_100.jsp'
keyword0 = '100'
keyword1 = '0.0'
keyword2 = '0.0'
title_list = []

def search_web():
    try:
        browser = webdriver.Chrome('./chromedriver')
        browser.get(url)
        
        search_input = browser.find_element_by_name('dt_page_in')
        search_input.send_keys(keyword0)

        search_input = browser.find_element_by_name('nm_yle')
        search_input.send_keys(keyword1)

        search_input = browser.find_element_by_name('nm_yls')
        search_input.send_keys(keyword2)
        
        browser.find_element_by_name('Submit3022233').click()
        
        get_titles(browser)

        page_no = 2

        search_word = '"JavaScript:fncPagnig('+str(page_no)+');"'
        page_source = browser.page_source
        while page_source.find(search_word) &gt; 0:
            browser.find_element_by_xpath('//a[@href='+search_word+']').click()
            get_titles(browser)
            page_no += 1
            search_word = '"JavaScript:fncPagnig('+str(page_no)+');"'
            
    finally:
        print('END')

    return title_list

def get_titles(page_text):
    titles = page_text.find_elements_by_xpath('//b')
    isTitle = 0
    for title in titles:
        if isTitle == 0 and title.text == '簡易検索：':
            isTitle = 1
        elif isTitle == 1 and title.text == 'ISBN検索：':
            isTitle = 2
        elif isTitle == 1:
            #print(title.text)
            title_list.append(title.text)

            
if __name__ == '__main__':
    search_web()
    print(title_list)
</pre>
<h3>プログラムソースの内容</h3>
<p>今回は、プログラムの冒頭で、以下のように空のリスト「title_list」を宣言します。</p>
<pre class="lang:python decode:true " >
title_list = []
</pre>
<p>search_web()で英語多読研究会さんのサイトからデータの取得処理を行います。</p>
<pre class="lang:python decode:true " >
browser = webdriver.Chrome('./chromedriver')
</pre>
<p>で、chromedriverを立ち上げて、send_keysで検索項目を指定し、<br />
下記のclick()で検索処理を実行するところまでは前回と同じです。</p>
<pre class="lang:python decode:true " >
browser.find_element_by_name('Submit3022233').click()
</pre>
<p>その後、以下でget_titles()を実行します。</p>
<pre class="lang:python decode:true " >
get_titles(browser)
</pre>
<p>取得した書名リストをtitle_listに追加します。</p>
<pre class="lang:python decode:true " >
title_list.append(title.text)
</pre>
<p>ここまで終わると、再びsearch_web()に戻ります。</p>
<p>ページャーのリンクは、以下のタグです。</p>
<pre class="lang:python decode:true " >
&lt;a href="JavaScript:fncPagnig(2);" style="color=blue;"&gt;2&lt;/a&gt;
</pre>
<p>これをクリックすることで2ページ目に遷移します。</p>
<p>ページャーがあると、&#8221;JavaScript:fncPagnig(2);&#8221; という文字列がページソース内に存在します。<br />
最初に page_no = 2 として、以下のようにsearch_wordという文字列を生成します。</p>
<pre class="lang:python decode:true " >
search_word = '"JavaScript:fncPagnig('+str(page_no)+');"'
</pre>
<p>3ページ以上あることも想定して、page_no をインクリメントし、<br />
その値で生成したsearch_wordで、ページソースを検索します。</p>
<pre class="lang:python decode:true " >
while page_source.find(search_word) &amp;gt; 0:
</pre>
<p>ページソース内にページャーがあった場合はwhileループ内を実行します。</p>
<p>まずは、以下でページャーのリンクをクリックします。</p>
<pre class="lang:python decode:true " >
browser.find_element_by_xpath('//a[@href='+search_word+']').click()
</pre>
<pre class="lang:python decode:true " >
get_titles(browser)
</pre>
<p>で検索結果ページから書名リストを取得します。</p>
<pre class="lang:python decode:true " >
page_no += 1
search_word = '"JavaScript:fncPagnig('+str(page_no)+');"'
</pre>
<p>でpage_noをインクリメントして、その値でリンク先の文字列を生成します。</p>
<p>while文で、この値（次のページのリンク）が存在するかを調べ、<br />
存在する場合は再度ループ内を実行します。</p>
<p>次ページが存在しない場合は、ループを抜けてプログラムを終了します。</p>
<p>次は、書名のリストをテキストファイルに書き出すことと、<br />
これまで固定だった検索項目（読みやすさレベル）を動かして<br />
それぞれの読みやすさレベルごとに書名リストのテキストファイルを<br />
生成することを実装したいと思います。</p><p>The post <a href="https://ichizo.biz/2016/12/28/python_selenium-2.html">英語多読用の本をレベル別に取得する（ページャーも対応）</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://ichizo.biz/2016/12/28/python_selenium-2.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">91</post-id>	</item>
		<item>
		<title>英語多読用の本のリストをレベル別に取得する</title>
		<link>https://ichizo.biz/2016/12/27/python_selenium.html</link>
					<comments>https://ichizo.biz/2016/12/27/python_selenium.html?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[一蔵]]></dc:creator>
		<pubDate>Tue, 27 Dec 2016 07:55:05 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[英語]]></category>
		<category><![CDATA[Selenium]]></category>
		<guid isPermaLink="false">http://ichizo.biz/?p=88</guid>

					<description><![CDATA[<p>英語多読用の本のリストをレベル別に取得したい 英語多読研究会 [&#8230;]</p>
<p>The post <a href="https://ichizo.biz/2016/12/27/python_selenium.html">英語多読用の本のリストをレベル別に取得する</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2>英語多読用の本のリストをレベル別に取得したい</h2>
<p>英語多読研究会さんが、<a href="http://www.seg.co.jp/sss_review/jsp/frm_a_100.jsp" target="_blank">英語多読に使える本のデータベース</a>を公開してくれています。<br />
読みやすさレベルを指定して検索することができるので、<br />
自分のレベルに合わせた本を探すのに非常に使い勝手がいいサイトになっています。</p>
<p>このリストから読みたい本を見つけて英語多読に役立てたいところですが、<br />
個別に本を買っていると結構お金がかかってしまいます。</p>
<p>そこで洋書も多いKindle Unlimitedで対象の本があれば<br />
月額980円で読み放題ということで、<br />
より英語多読がやりやすくなります。</p>
<p>ということで、英語多読に役立てたいという目的で、<br />
英語多読研究会さんのデータベースからレベル別に<br />
本のリストを取得することを考えてみます。</p>
<h3>Seleniumを使おう</h3>
<p>レベル別に英語本のリストを取得するには、<br />
検索画面に抽出したいレベルを指定して<br />
検索要求を投げる必要があります。</p>
<p>最初はPythonスクリプトからRequestsを使って<br />
リスト取得することを考えました。</p>
<p>検索項目等の指定をした上で検索要求を投げる訳ですが、<br />
再び検索画面が表示されるだけで、なぜか検索結果画面が表示されません。<br />
（検索画面と検索結果画面のURLが同じで、どうにも受け渡しているパラメーターによって切り替えているっぽいです）</p>
<p>Requestsでヘッダ情報をセットしたり、<br />
検索画面で受け取ったクッキーを検索要求で渡すなどやってみましたが<br />
うまくいかずRequestsでの検索要求はやめることにしました。<br />
（ブラウザから渡しているhidden項目等を渡してみましたがことごとくダメでした）</p>
<p>ということでSeleniumでブラウザを操作して検索結果を取得してみます。</p>
<h3>Seleniumを操作するプログラム</h3>
<p>まずはプログラムソースを。</p>
<p>前回の記事「<a href="http://ichizo.biz/2016/12/22/python-selenium.html">PythonとSeleniumでブラウザの自動操作</a>」で作成したソースを改変します。</p>
<pre class="lang:python decode:true " title="selenium_english.py" >
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 22 16:32:48 2016

@author: 
"""

from selenium import webdriver

url = 'http://www.seg.co.jp/sss_review/jsp/frm_a_100.jsp'
keyword0 = '100'
keyword1 = '0.0'
keyword2 = '0.0'


def search_web():
    try:
        browser = webdriver.Chrome('./chromedriver')
        browser.get(url)
        
        search_input = browser.find_element_by_name('dt_page_in')
        search_input.send_keys(keyword0)

        search_input = browser.find_element_by_name('nm_yle')
        search_input.send_keys(keyword1)

        search_input = browser.find_element_by_name('nm_yls')
        search_input.send_keys(keyword2)
        
        browser.find_element_by_name('Submit3022233').click()
        
        #print(browser.page_source)
        titles = browser.find_elements_by_xpath('//b')
        isTitle = 0
        for title in titles:
            if isTitle == 0 and title.text == '簡易検索：':
                isTitle = 1
            elif isTitle == 1 and title.text == 'ISBN検索：':
                isTitle = 2
            elif isTitle == 1:
                print(title.text)
            #booktext = bookdata.text

        
    finally:
        print('END')


if __name__ == '__main__':
    search_web()
</pre>
<h3>プログラムソースの解説</h3>
<p>keyword0 = &#8216;100&#8217;で、表示件数（100件）、<br />
keyword1 = &#8216;0.0&#8217;とkeyword2 = &#8216;0.0&#8217;で読みやすさレベルを設定しておきます。</p>
<pre class="lang:python decode:true " >
browser = webdriver.Chrome('./chromedriver') 
</pre>
<p>で、Pythonスクリプトと同じディレクトリ内に置いたchrmedriverを読み込みます。<br />
browser.get(url) で指定したURLを開きます。</p>
<pre class="lang:python decode:true " >
search_input = browser.find_element_by_name('dt_page_in')
search_input.send_keys(keyword0)
</pre>
<p>で、dt_page_inにkeyword0（100）をセットします。</p>
<p>同様に「nm_yle」と「nm_yls」に検索項目である読みやすさレベルを指定します。</p>
<pre class="lang:python decode:true " >
browser.find_element_by_name('Submit3022233').click()
</pre>
<p>で検索ボックスをクリックします。</p>
<p>検索結果ページはbrowserに入っていて、<br />
書名は「bタグ」で囲まれているので、書名リストをfind_elements_by_xpathで取得します。</p>
<pre class="lang:python decode:true " >
titles = browser.find_elements_by_xpath('//b')
</pre>
<p>titlesにbタグで囲まれた書名のリストが入っていますが、<br />
それ以外のbタグで囲まれた部分もリストに入っているので、<br />
以下で取り除きます。</p>
<pre class="lang:python decode:true " >
isTitle = 0
for title in titles:
    if isTitle == 0 and title.text == '簡易検索：':
        isTitle = 1
    elif isTitle == 1 and title.text == 'ISBN検索：':
        isTitle = 2
    elif isTitle == 1:
        print(title.text)
</pre>
<p>ここまでで、検索を実行して表示された検索結果ページから<br />
書名のリストを取得する（ただし最初の1ページ目のみ）ということができました。</p>
<p>引き続いて次回は、検索結果が複数ページに渡る場合に<br />
画面を遷移させた上で書名リストを取得し、<br />
これをテキストファイルに出力するということを行います。</p>
<p>Pythonって直観的で使いやすい言語ですね。</p><p>The post <a href="https://ichizo.biz/2016/12/27/python_selenium.html">英語多読用の本のリストをレベル別に取得する</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://ichizo.biz/2016/12/27/python_selenium.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">88</post-id>	</item>
		<item>
		<title>英語多読用リストがKindle Unlimitedに存在するか自動チェックしてみる</title>
		<link>https://ichizo.biz/2016/12/20/english-kindle-unlimited.html</link>
					<comments>https://ichizo.biz/2016/12/20/english-kindle-unlimited.html?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[一蔵]]></dc:creator>
		<pubDate>Tue, 20 Dec 2016 08:50:13 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[英語]]></category>
		<category><![CDATA[Amazon Product Advertising API]]></category>
		<category><![CDATA[bottlenose]]></category>
		<category><![CDATA[Kindle Unlimited]]></category>
		<guid isPermaLink="false">http://ichizo.biz/?p=73</guid>

					<description><![CDATA[<p>PythonでAmazonのKindle Unlimited [&#8230;]</p>
<p>The post <a href="https://ichizo.biz/2016/12/20/english-kindle-unlimited.html">英語多読用リストがKindle Unlimitedに存在するか自動チェックしてみる</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><a href="http://ichizo.biz/2016/12/20/python-kindleunlimited.html">PythonでAmazonのKindle Unlimited情報を取得してみる</a>に続いて、<br />
あらかじめテキストファイルに記載していた書名を取得して<br />
Amazon Product Advertising APIに対して検索を行います。</p>
<h2>Pythonでテキストファイルを開く</h2>
<p>テキストファイルは、以下のようなソースで読み込みます。</p>
<pre class="lang:python decode:true " >
#!/usr/bin/env python

f = open('text.txt', 'r')

for line in f:
    print line
    
f.close()
</pre>
<p>読み込みたいのは以下のようなテキストファイルです。</p>
<pre class="lang:default decode:true " >
Foundations Reading Library
Penguin Readers Easystarts
Oxford Bookworms Starters
Macmillan Readers Starter
Macmillan New Wave Readers Level 1
Oxford Reading Tree
Longman Literacy Land Story Street
Macmillan Springboard
Rookie Readers Fiction
Cambridge Storybooks
Longman Shared Reading
Oxford Start with English Readers
Longman Big and Little Books
CTP Emergent Readers
100 English
Sight Word Readers
Time-to-Discover Readers
Step into Reading Step 1
Step into Reading Step 2
Scholastic Reader Level1
Scholastic Reader Level2
My First I Can Read Books
I Can Read Books Level 1
Penguin Young Readers Level 1
Ready-to-Read Pre-Level 1
Ready-to-Read Level 1
Ready-to-Read Level 2
All Aboard Reading Picture Books
All Aboard Reading Level 1
Puffin Easy-to-Read Level 1
Addison Wesley Big and Little Books
Oxford Classic Tales
Curious George Short Stories
Dorling Kindersley Readers Level 1
Dorling Kindersley Readers Level 2
Oxford Dominoes Stage 0
Penguin Young Readers Level 2
Longman Chatterbox
TL PM Readers
HM Leveled Reading Grade 1
The Very Hungry Caterpillar
Good Night Moon
Brown Bear, Brown Bear, What Do You See?
</pre>
<h3>英語多読用の本のリストが欲しい</h3>
<p>これは何かというと、英語多読用の本のリストです。</p>
<p>SSS英語多読研究会がすすめる「<a href="https://www.seg.co.jp/sss/learning/" target="_blank">非常にやさしい本からはじめ、１００万語単位で読む多読</a>」をやってみたいと思っていたのですが、<br />
多読をするためにはまず教材となる英語の本を用意する必要があります。</p>
<p>SSS英語多読研究会では、<a href="https://www.seg.co.jp/sss/review/osusume.html" target="_blank">レベル別に読むべき本を紹介してくれています</a>。</p>
<p>問題は、多読をするためには大量の本を読まなければいけないのですが、<br />
目安である100万語まで到達するまでにはかなりの本が必要になります。</p>
<p>特にレベルの低いころに読む本は、1冊あたりの字数が少ないために<br />
どうしても本の数が多くなってしまいます。</p>
<p>１冊500円～600円程度で購入できるので、数冊買う分にはいいのですが、<br />
多読となると数十冊単位で読む必要があります。<br />
となると、数万円は軽くかかります。</p>
<p>しかもそのレベルを通り過ぎてしまえば、必要がなくなってしまうという<br />
悲しい運命が待っています。<br />
簡単なものから始めるがゆえに、ほぼ読み捨てしなければならないということです。</p>
<p>そこで目を付けたのが、Kindle Unlimitedです。</p>
<p>読み放題のKindle Unlimitedであれば、お金を気にせず読み進められます。<br />
洋書もかなりの冊数あります（先ほど洋書一覧で見ると137万冊以上あるようです）ので、<br />
きっと多読に使える本もあるはずということです。</p>
<p>ただ、ここで問題になるのは対象になる本を見つける方法です。<br />
リストにあがっている本をいちいち検索するのはメンドくさい、<br />
そもそもKindle Unlimitedにない本もある（ないことが多い）、<br />
効率よく多読するには本を効率よく見つけることも大切だということで<br />
リストからKindle Unlimitedにあるのかを探すプログラムを作ることにしました。</p>
<p>今回検索するリストは、SSS英語多読研究会がレベル0として推薦しているものです。</p>
<h3>書名リストからAmazon Product Advertising APIを呼び出すプログラム</h3>
<p>書名リストのテキストをlevel0.txtとして、Pythonプログラムと同じディレクトリに置きます。</p>
<p>前回の「<a href="http://ichizo.biz/2016/12/20/python-kindleunlimited.html">PythonでAmazonのKindle Unlimited情報を取得してみる</a>」に、ファイルの読み込み処理を組み込みます。</p>
<p>修正したプログラムが以下です。</p>
<pre class="lang:python decode:true " >
# -*- coding: utf-8 -*-
"""
Created on Mon Dec 19 14:49:19 2016

@author: 
"""

from bottlenose import api
from lxml import objectify
import time

AMAZON_ACCESS_KEY_ID = "アクセスキー"
AMAZON_SECRET_KEY = "シークレットキー"
AMAZON_ASSOC_TAG = "アソシエイトタグ"

KINDLE_UMLIMITED_NODE_ID = "4486610051"

amazon = api.Amazon(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, Region = "JP")

def file_read (file):
    f = open(file, 'r')
    data = f.read()
    f.close()
    lines = data.split('\n')
    return lines

def item_search (keywords, searchIndex="KindleStore", browseNode=KINDLE_UMLIMITED_NODE_ID):
    response = amazon.ItemSearch(Keywords=keywords, SearchIndex=searchIndex, BrowseNode=browseNode, ResponseGroup="Large")
    root = objectify.fromstring(response)
    return root.Items.Item

if __name__ == '__main__':

    lines = file_read('level0.txt')
    for line in lines:
        for item in item_search(line):
            title = item.ItemAttributes.Title
            author = item.ItemAttributes.Author
            url = item.DetailPageURL
            print ("%s\n%s\n%s\n%s\n\n" % (line, title, author, url))
        time.sleep(5)   # Amazon API呼び出しは1秒に1回以内に収めるためsleep
</pre>
<p>file_readというメソッドを作って、ここでテキストファイルを読み込み<br />
１行ずつを配列の各要素に入れて返します。</p>
<p>file_readの呼び出し元では、返り値でループさせます。<br />
その際に、sleep(5)を入れています。</p>
<p>これで実行してみると、<br />
「AttributeError: no such child: {http://webservices.amazon.com/AWSECommerceService/2013-08-01}Item」<br />
というエラーで終了します。</p>
<p>APIの結果がない場合にエラーで落ちてしまっています。<br />
今度はこれの対策を考えます。</p>
<p>以下のように書き換えてみました。</p>
<pre class="lang:python decode:true " >
# -*- coding: utf-8 -*-
"""
Created on Mon Dec 19 14:49:19 2016

@author: 
"""

from bottlenose import api
from lxml import objectify
import time

AMAZON_ACCESS_KEY_ID = "アクセスキー"
AMAZON_SECRET_KEY = "シークレットキー"
AMAZON_ASSOC_TAG = "アソシエイトタグ"

KINDLE_UMLIMITED_NODE_ID = "4486610051"

amazon = api.Amazon(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, Region = "JP")

def file_read (file):
    f = open(file, 'r')
    data = f.read()
    f.close()
    lines = data.split('\n')
    return lines

def item_search (keywords, searchIndex="KindleStore", browseNode=KINDLE_UMLIMITED_NODE_ID):
    response = amazon.ItemSearch(Keywords=keywords, SearchIndex=searchIndex, BrowseNode=browseNode, ResponseGroup="Large")
    root = objectify.fromstring(response)
    return root.Items

if __name__ == '__main__':

    lines = file_read('level0.txt')
    for line in lines:
        items = item_search(line)
        item_find = items.find('Item')
        if (item_find is not None):
            for item in item_find:
                if (item is not None):
                    title = item.ItemAttributes.Title
                    author = item.ItemAttributes.Author
                    url = item.DetailPageURL
                    print ("%s\n%s\n%s\n%s\n\n" % (line, title, author, url))
                else:
                    print ("%s : Book is None" % (line))
        print ("END %s" % (line))
        time.sleep(5)   # Amazon API呼び出しは1秒に1回以内に収めるためsleep
</pre>
<p>調べてみると、「root.Items.find(&#8216;Item&#8217;)」は、<br />
Itemが空の時Noneを返すということなので、<br />
「items.find(&#8216;Item&#8217;)」をitem_findに放り込んで<br />
これがNoneの場合は処理しないようにしました。</p>
<p>結果はというと、以下のようになりました。</p>
<pre class="lang:default decode:true " >
END Foundations Reading Library
END Penguin Readers Easystarts
END Oxford Bookworms Starters
END Macmillan Readers Starter
END Macmillan New Wave Readers Level 1
END Oxford Reading Tree
END Longman Literacy Land Story Street
END Macmillan Springboard
END Rookie Readers Fiction
END Cambridge Storybooks
END Longman Shared Reading
END Oxford Start with English Readers
END Longman Big and Little Books
END CTP Emergent Readers
END 100 English
END Sight Word Readers
END Time-to-Discover Readers
END Step into Reading Step 1
END Step into Reading Step 2
END Scholastic Reader Level1
END Scholastic Reader Level2
END My First I Can Read Books
END I Can Read Books Level 1
END Penguin Young Readers Level 1
END Ready-to-Read Pre-Level 1
END Ready-to-Read Level 1
END Ready-to-Read Level 2
END All Aboard Reading Picture Books
END All Aboard Reading Level 1
END Puffin Easy-to-Read Level 1
END Addison Wesley Big and Little Books
END Oxford Classic Tales
END Curious George Short Stories
END Dorling Kindersley Readers Level 1
END Dorling Kindersley Readers Level 2
END Oxford Dominoes Stage 0
END Penguin Young Readers Level 2
END Longman Chatterbox
END TL PM Readers
END HM Leveled Reading Grade 1
END The Very Hungry Caterpillar
END Good Night Moon
END Brown Bear, Brown Bear, What Do You See?
END 
</pre>
<p>結果は全滅・・・。<br />
一つもKindle Unlimitedにはないという結果に。</p>
<p>そしてなぜか「if (item is not None):」のelse部分を通ってくれなかったという謎も。</p>
<p>リストを広げて再取得してみることにします。</p><p>The post <a href="https://ichizo.biz/2016/12/20/english-kindle-unlimited.html">英語多読用リストがKindle Unlimitedに存在するか自動チェックしてみる</a> first appeared on <a href="https://ichizo.biz">イチゾーのブログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://ichizo.biz/2016/12/20/english-kindle-unlimited.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">73</post-id>	</item>
	</channel>
</rss>
