pythonでコードを書いて、AmazonのサイトからASINコードと金額のデータを、普通にスクレイピングしてみたけど出来なかった。
(バグだと思って何時間も無駄にした)
どうやらAmazonのサイトはスクレイピングを禁止しているようだ。
厳密にいうと完全に禁止ではないようだけど、普通にやろうとすると出来ないようになっているので、禁止と認識しておくべきかな。
出品者としてAPIを使用すれば出来るみたいだけど、なんかめんどくさくて・・・
そこで、seleniumを使って
「人が操作してますよ!」
のふりをしてスクレイピングしてみた。
コード
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup as bs
import re
import time
inp=input()
amazon='https://www.amazon.co.jp/'
class get_sous:
def __init__(self,url,browser):
self.url=url
self.browser=browser
def getbrowser(self):
sous=self.browser.page_source
self.browser.close()
return sous
def openurl(self):
self.browser.get(self.url)
time.sleep(5)
def search_(self,name):
search_name=self.browser.find_element_by_id('twotabsearchtextbox')
search_name.clear()
search_name.send_keys(name)
btn=self.browser.find_element_by_class_name("nav-input")
btn.click()
time.sleep(5)
webd=webdriver.Chrome()
open1=get_sous(amazon,webd)
open1.openurl()
sous1=open1.search_(inp)
sous1=open1.getbrowser()
soup=bs(sous1, 'html.parser')
link1=soup.find_all('a',class_="a-link-normal a-text-normal")
link1=(link1[0].get('href'))
open2=get_sous(amazon+link1,webdriver.Chrome())
open2.openurl()
sous2=open2.getbrowser()
soup=bs(sous2, 'html.parser')
name=soup.find("span",id='productTitle')
name=(name.get_text().strip())
print(name)
price=soup.find("span",id='priceblock_ourprice')
price=re.sub(r'\,','',price.get_text())
print(price)
asin=soup.find("input",class_="askAsin")
print(asin.get('value'))
上記のスクリプトをとりあえず作ってみました。
中身の説明
まずは、ライブラリーのインポート
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup as bs
import re
import time
selenium:ブラウザの操作に使用
bs4:htmlからデータを抽出できるようにする
re:正規表現
time:ブラウザが立ち上がるまで時間稼ぎに使用
inp=input()
amazon='https://www.amazon.co.jp/'
inp変数に検索したい項目を入力
amazon変数にアマゾンのURLを代入
class get_sous:
def __init__(self,url,browser):
self.url=url
self.browser=browser
def getbrowser(self):
sous=self.browser.page_source
self.browser.close()
return sous
def openurl(self):
self.browser.get(self.url)
time.sleep(5)
def search_(self,name):
search_name=self.browser.find_element_by_id('twotabsearchtextbox')
search_name.clear()
search_name.send_keys(name)
btn=self.browser.find_element_by_class_name("nav-input")
btn.click()
time.sleep(5)
get_sousクラス
def __init__ :イニシャライザ、クラスの初期化
def getbrowser :ブラウザのhtmlを取得して、ブラウザを閉じる
def openurl : ブラウザを開いて、5秒待機する
def search_ :Amazonサイトの検索欄の中を一度クリアし、検索内容を入力してボタンをクリック。その後 5秒待機する 。
webd=webdriver.Chrome()
open1=get_sous(amazon,webd)
open1.openurl()
sous1=open1.search_(inp)
sous1=open1.getbrowser()
webdにChromeのドライバを代入
get_sousクラスに引数をいれてインスタンス化
関数を3個動かす(詳細は上記のクラス説明で記述済み)
soup=bs(sous1, 'html.parser')
link1=soup.find_all('a',class_="a-link-normal a-text-normal")
link1=(link1[0].get('href'))
検索して上位一番目に出てきたリンクのURLをlink1に代入する
open2=get_sous(amazon+link1,webdriver.Chrome())
open2.openurl()
sous2=open2.getbrowser()
先ほど取得したリンク先を開いて、ブラウザのHTMLデータを取得
soup=bs(sous2, 'html.parser')
name=soup.find("span",id='productTitle')
name=(name.get_text().strip())
print(name)
BeautifulSoupでHTMLを扱えるじょうたいにする
findでタグから商品名を抽出
抽出したテキストの前後に要らないスペースがあるので、「strip()」で削除
pirntで表示
price=soup.find("span",id='priceblock_ourprice')
price=re.sub(r'\,','',price.get_text())
print(price)
asin=soup.find("input",class_="askAsin")
print(asin.get('value'))
あとは金額とasinコードを抽出して表示
※カテゴリー別なのか検証は出来てませんが、金額とasinコードのデータのある場所がバラバラで、抽出できるものと出来ない物がありました。
何パターンあるのか不明なので今後検証が必要ですね。
これを元に、リスト化された検索対象からデータの抽出を自動化できそうです。
※このコードは素人が個人的な勉強の一環で書いたコードです。
このコードを利用しての責任は一切負いませんのでよろしくお願い致します。