質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.58%

リスト型についてのプログラム

受付中

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 536
退会済みユーザー

退会済みユーザー

 前提・実現したいこと

Tripadvisorのレビューをスクレイピングで抽出しているのですが、抽出する際に観光地のURLをプログラム内で入力しております。
その際に、現在は1つのURLを入力する形の為、複数のURLを入力して取得したい為リスト型で組んだのですがプログラムが動かないので実現したいです。

 発生している問題・エラーメッセージ

  File "run_get_review.py", line 294, in <module>
    url_en = url_jp.replace("https://www.tripadvisor.jp/", "https://www.tripadvisor.com/")
AttributeError: 'list' object has no attribute 'replace'

 該当のソースコード

# -*- coding:utf-8 -*-
#レビュー抽出 実行ファイル


from bs4 import BeautifulSoup
import urllib.request
import urllib.parse
import random
from time import sleep
import os
import codecs

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

### "次へ"のページのurl取得 1
### レビューのページ数分のurl(1,2,…最後 までのurl)
def Get_nextpage_url_jp(url):
    links = []
    opener = urllib.request.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
    html = opener.open(url)
    soup = BeautifulSoup(html,"lxml")

    spotname = soup.find("h1",{"class":"ui_header h1"}).get_text().strip() # タグ指定
    links.append(url)
    #次のページのurl(最後の口コミのとこまで)
    for url2 in links:
        html = opener.open(url2)
        soup = BeautifulSoup(html,"lxml")
        try:
            link = soup.find("a",{"class":"nav next taLnk "}).get("href") # タグ指定
            links.append("https://www.tripadvisor.jp" + link)
        except:
            try:
                link = soup.find("a",{"class":"nav next taLnk ui_button primary"}).get("href") # タグ指定
                links.append("https://www.tripadvisor.jp" + link)
            except:
                print("Not next")
    return links, spotname

### レビューの詳細ページ取得 2
def Get_review_url_jp(url):
    links = []
    opener = urllib.request.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
    html = opener.open(url)
    soup = BeautifulSoup(html,"lxml")

    #url取得
    for div in soup.find_all("div",{"class":"ui_column is-9"}):
        try:
            links.append("https://www.tripadvisor.jp" + div.a.get("href"))
        except:
            print("not url")
    return links

### 英語 1
def Get_review_url_en(url):
    links = []
    opener = urllib.request.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
    html = opener.open(url)
    soup = BeautifulSoup(html,"lxml")

    #url取得
    for div in soup.find_all("div",{"class":"ui_column is-9"}):
        try:
            links.append("https://www.tripadvisor.com" + div.a.get("href"))
        except:
            print("not url")
    return links

### 英語 2
def Get_nextpage_url_en(url):
    links = []
    opener = urllib.request.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
    html = opener.open(url)
    soup = BeautifulSoup(html,"lxml")

    spotname = soup.find("h1",{"class":"ui_header h1"}).get_text().strip() # タグ指定
    links.append(url)
    #次のページのurl(最後の口コミのとこまで)
    for url2 in links:
        html = opener.open(url2)
        soup = BeautifulSoup(html,"lxml")
        try:
            link = soup.find("a",{"class":"nav next taLnk "}).get("href") # タグ指定
            links.append("https://www.tripadvisor.com" + link)
        except:
            try:
                link = soup.find("a",{"class":"nav next taLnk ui_button primary"}).get("href") # タグ指定
                links.append("https://www.tripadvisor.com" + link)
            except:
                print("Not next")
    return links, spotname



### review取得 3
def Get_review_data(url):
    try:
        title = [] #タイトル
        review = [] #レビュー
        opener = urllib.request.build_opener()
        opener.addheaders = [('User-agent', 'Mozilla/5.0')]
        html = opener.open(url)
        soup = BeautifulSoup(html, "lxml")

        #タイトル抽出1つ
        try:
            t = soup.find("h1",{"class":"title"})
            title = t.get_text().replace("\n","").replace("\r","").replace(",", "").strip()
        except:
            t = soup.find("span",{"class":"noQuotes"})
            title = t.get_text().replace("\n","").replace("\r","").replace(",", "").strip()
#        for url in soup.find_all("span",{"class":"noQuotes"}): # 必要なタグ指定

        #レビュー抽出1つ
        try:
            r = soup.find("span",{"class":"fullText "})
            review = r.get_text().replace(",", "").replace("\n", "").replace("\r\n", "").replace("\r","").strip()
        except:
            r = soup.find("p",{"class":"partial_entry"})
            review = r.get_text().replace(",", "").replace("\n", "").replace("\r\n", "").replace("\r","").strip()
    except:
        import traceback
        traceback.print_exc()

    return title, review # [文字列, 文字列]


### 取得してきたもの全てをcsvファイルに保存 4
def Save_path(name):
    path = os.getcwd() # このプログラムの場所
    savdir = "\\review\\" # "review"を保存するディレクトリ
    if os.path.isdir(path + savdir) == False: # "review"というフォルダが無ければ作成
        os.mkdir(path + savdir)
    filename = name + ".csv"
    filepath = path + savdir + filename
    return filepath

def Write_file(filepath, data):
    #ファイルに書き込み w:上書き a:追記
    file_object= codecs.open(filepath, "a", "cp932", "ignore")
    file_object.write(str(data) + "\n")
    file_object.close()



### 実行部分_jp
def Start_extract_review_jp(start_url):
    #各値 初期化
    title = []
    review = []
    links = []
    urls = []

    print("get_nextpage_url:  Start")
    try:
        links, spotname = Get_nextpage_url_jp(start_url)
    except:
        print("get_nextpage_url is error")
    print("Total Next url =  " + str(len(links)))
    print("get_review_url:  Start")
    #1つずつurlを
    for link in links:
        try:
            urls.extend(Get_review_url_jp(link)) #必要
        except:
            print("get_review_url is error")
    print("Total review =  " + str(len(urls)))
    #urls = review数
    print("Get_review_data:  Start")
    debug = 0

    #filename指定してcsvに保存
    try:
        filepath = Save_path(spotname)
    except:
        print("Save_path is error")

    #file_open
    file_object= codecs.open(filepath, "a", "cp932", "ignore")
    for url in urls:
        debug += 1
        print("review = " + str(debug))

        interval = 5 + random.uniform(-3.0, 3.0)
        print("interval 1: begin")
        sleep(interval)
        print("interval 1: end")

        try:
            title, review = Get_review_data(url)
        except:
            print("Get_review_data is error")

        file_object.write("{}\s{}\n".format(str(title), str(review)))

    file_object.close()
    print("save: Complete")

### 実行部分_jp
def Start_extract_review_en(start_url):
    #各値 初期化
    title = []
    review = []
    links = []
    urls = []

    print("get_nextpage_url:  Start")
    try:
        links, spotname = Get_nextpage_url_en(start_url)
    except:
        print("get_nextpage_url is error")
    print("Total Next url =  " + str(len(links)))
    print("get_review_url:  Start")
    #1つずつurlを
    for link in links:
        try:
            urls.extend(Get_review_url_en(link)) #必要
        except:
            print("get_review_url is error")
    print("Total review =  " + str(len(urls)))
    #urls = review数
    print("Get_review_data:  Start")
    debug = 0

    #filename指定してcsvに保存
    try:
        filepath = Save_path(spotname)
    except:
        print("Save_path is error")

    #file_open
    file_object= codecs.open(filepath, "a", "cp932", "ignore")
    for url in urls:
        debug += 1
        print("review = " + str(debug))

        interval = 5 + random.uniform(-3.0, 3.0)
        print("interval 1: begin")
        sleep(interval)
        print("interval 1: end")

        try:
            title, review = Get_review_data(url)
        except:
            print("Get_review_data is error")

        file_object.write("{}\s{}\n".format(str(title), str(review)))

    file_object.close()
    print("save: Complete")


if __name__ =='__main__':

    """
    #debug Get_next_url
    #"次へ"のページのurl取得 1
    #url = "https://www.tripadvisor.jp/Attraction_Review-g1022838-d1548549-Reviews-Takosenbei_no_Sato-Awaji_Awaji_shima_Hyogo_Prefecture_Kinki.html" #最初のページ
    url = "https://www.tripadvisor.com/Attraction_Review-g1022838-d1548549-Reviews-Takosenbei_no_Sato-Awaji_Awaji_shima_Hyogo_Prefecture_Kinki.html"
    links = Get_nextpage_url_jp(url)
    print(links)
    """

    """
    #debug Get_review_url
    # レビューの詳細ページ取得 2
    #url = "https://www.tripadvisor.jp/Attraction_Review-g298562-d1384635-Reviews-Suma_Rikyu_Park-Kobe_Hyogo_Prefecture_Kinki.html"
    url = "https://www.tripadvisor.com/Attraction_Review-g1022838-d1548549-Reviews-Takosenbei_no_Sato-Awaji_Awaji_shima_Hyogo_Prefecture_Kinki.html"
    links = Get_review_url(url)
    print(links)
    """

    """
    #debug Get_review_data
    # review 取得 3
    #url = "https://www.tripadvisor.jp/ShowUserReviews-g298562-d1384635-r631487360-Suma_Rikyu_Park-Kobe_Hyogo_Prefecture_Kinki.html"
    #url = "https://www.tripadvisor.jp/ShowUserReviews-g1022838-d1548549-r631449250-Takosenbei_no_Sato-Awaji_Awaji_shima_Hyogo_Prefecture_Kinki.html"
    url = "https://www.tripadvisor.com/ShowUserReviews-g1022838-d1548549-r536077279-Takosenbei_no_Sato-Awaji_Awaji_shima_Hyogo_Prefecture_Kinki.html"
    title, review = Get_review_data(url)
    print("{}\s{}".format(title,review))
    """

    #"""
    ###手打ち###
    url_jp = ["https://www.tripadvisor.jp/Attraction_Review-g1022818-d1724619-Reviews-Uontana_Shopping_Street-Akashi_Hyogo_Prefecture_Kinki.html","https://www.tripadvisor.jp/Attraction_Review-g298192-d1604489-Reviews-Aeon_Mall_Itami-Itami_Hyogo_Prefecture_Kinki.html"]
    ############

    url_en = url_jp.replace("https://www.tripadvisor.jp/", "https://www.tripadvisor.com/")

    Start_extract_review_jp(url_jp)
    Start_extract_review_en(url_en)
    #"""
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

0

処理詳細は見ていませんが、こういうことでしょうか?

    url_jp = ["https://www.tripadvisor.jp/Attraction_Review-g1022818-d1724619-Reviews-Uontana_Shopping_Street-Akashi_Hyogo_Prefecture_Kinki.html","https://www.tripadvisor.jp/Attraction_Review-g298192-d1604489-Reviews-Aeon_Mall_Itami-Itami_Hyogo_Prefecture_Kinki.html"]

    url_en = []
    for url in url_jp:
        url_en.append(url.replace("https://www.tripadvisor.jp/", "https://www.tripadvisor.com/"))

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

    url_en = [url.replace("https://www.tripadvisor.jp/", "https://www.tripadvisor.com/") for url in url_jp]

で質問文に記載されたエラーは消えますが、残念ながら他の関数(Start_extract_review_jp()など、すべて)がURLのlistを受け取る仕様になっていないので、動かないでしょう。

期待通りの動作かどうかはわかりませんが、こんな感じでURLごとに個別に動かせばとりあえずちゃんと動き始めはするようです(時間かかるので最後まで回していません)。

    for url in url_jp:
        Start_extract_review_jp(url)

    for url in url_en:
        Start_extract_review_en(url)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る