• 締切済み

pythonのfor文のエラーについて

現在pythonでwebスクレイピングの勉強をしている者です。 質問があるのですが、 from selenium import webdriver browser=webdriver.Chrome() browser.get("https://movie.jorudan.co.jp/cinema/") #クラスからリンクを抜き出してクリックさせる。 siwake=[] elems=browser.find_elements_by_class_name("item-body") for i in elems:  elem=i.find_element_by_tag_name("a")  elem.click() #クラスのジャンルからaタグのテキストを抜き出して前のページに戻る。  elem=browser.find_element_by_class_name("genre")  elem=elem.find_element_by_tag_name("a").text  browser.back()   #抜き出した情報をsiwakeの空のリストに追加する。  siwake.append(elem) 上記のコードで映画のジャンルの一つ目を抜き取りたいのですが、for文を回すとエラーが出てしまいます。 エラーとしては、 elems=browser.find_elements_by_class_name("item-body") for i in elems: ……→elem=i.find_element_by_tag_name("a") 上の一文がエラーとして出てきます。 また、一番下にはMessage:stale element reference: element is not attached to the page document という表記が出てきます。   どなたか原因が解る方がいらっしゃいましたらご教示して頂けると幸いです。 参考HPはhttps://movie.jorudan.co.jp/cinema/です。 よろしくお願い致します。

  • 8937
  • お礼率66% (2/3)
  • Python
  • 回答数1
  • ありがとう数1

みんなの回答

  • Proof4
  • ベストアンサー率78% (151/192)
回答No.1

このエラーはbrowser.back()で前のページに戻った後、elem=i.find_element_by_tag_name("a")で要素を探すまでにページの読み込みが完了していないことが原因だと思われます。 element_to_be_clickableなどを用いれば、対象の要素が読み込まれてからクリックするというのも可能ですが、ここでは異なるアプローチで解決します。 そもそも、browser.back()で戻るページは何度も表示される上に内容が同じであるため、無駄な動作が多くなっています。 1回の訪問で取得したい情報はすべて取ってしまい、同じページにアクセスする回数は可能な限り少ないほうが効率が良いです。 from selenium import webdriver browser=webdriver.Chrome() browser.get("https://movie.jorudan.co.jp/cinema/") #クラスからリンクを抜き出してクリックさせる。 siwake=[] elems=browser.find_elements_by_class_name("item-body") # リンク先のURLをすべて取得 link_hrefs = [] for i in elems:  link_hrefs.append(i.find_element_by_tag_name("a").get_attribute("href")) # リンク先のURLをループ for href in link_hrefs:  browser.get(href)  # クラスのジャンルからaタグのテキストを抜き出して前のページに戻る。  elem=browser.find_element_by_class_name("genre")  elem=elem.find_element_by_tag_name("a").text  # 抜き出した情報をsiwakeの空のリストに追加する。  siwake.append(elem) ※OKWAVEの仕様により、インデントを全角スペースで表現しています。コピペの際はご注意ください。 上記に示すコードでは、リンク先である映画の詳細ページのURLを一度にすべて取得してしまい、後でURLのリストをループして各詳細ページにアクセスします。 こうすることで、読み込むページの数をおよそ半分にすることができます。もちろん、要素が見つからない問題も解決されます。

8937
質問者

お礼

ご丁寧に回答していただきありがとうございました! 早速実践してみます!!

関連するQ&A

  • pythonのfor文のエラーについて

    現在pythonでwebスクレイピングの勉強をしている者です。 質問があるのですが、 from selenium import webdriver browser=webdriver.Chrome() browser.get("https://movie.jorudan.co.jp/cinema/") #クラスからリンクを抜き出してクリックさせる。 siwake=[] elems=browser.find_elements_by_class_name("item-body") for i in elems: elem=i.find_element_by_tag_name("a") elem.click() #クラスのジャンルからaタグのテキストを抜き出して前のページに戻る。   elem=browser.find_element_by_class_name("genre") elem=elem.find_element_by_tag_name("a").text browser.back()   #抜き出した情報をsiwakeの空のリストに追加する。 siwake.append(elem) 上記のコードで映画のジャンルの一つ目を抜き取りたいのですが、for文を回すとエラーが出てしまいます。 どなたか原因が解る方がいらっしゃいましたらご教示して頂けると幸いです。 参考HPはhttps://movie.jorudan.co.jp/cinema/です。 よろしくお願い致します。

  • pythonでエクセルにコピペできない

    pythonでWebページにログインし、レポートを全選択して エクセルにペーストしたいのですが、エクセルにペーストできないです。 どのように修正したら良いのでしょうか? よろしくお願いします。 【確認したこと】 1.エクセルは更新履歴が変わっているので、開いて保存はしている。 2.プログラム終了後、手動でエクセルを開いてctrl+vするとコピーした値をペーストできる。(クリップボードにはコピーされている) 3.新規エクセルで試してもペーストできない。 import time import chromedriver_binary import pyautogui import openpyxl from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome import service wb = openpyxl.load_workbook("./BOS_Data.xlsx") #WEBブラウザの起動 driver = webdriver.Chrome() #自動ログインしたいウェブサイトのURLをコピペ driver.get('https://xxx/Login/default.asp') USER = 'o2' PASS = 'M3' my_id = driver.find_element(By.NAME, 'sUserName') password = driver.find_element(By.NAME, 'sPassword') submit_btn = driver.find_element(By.NAME, 'submit') #自動入力したIDとパスワードを入力 my_id.send_keys(USER) password.send_keys(PASS) #ログインボタンを自動入力 submit_btn.click() #Reportをクリック driver.find_element(By.XPATH, '/xxxxxxxx).click() #全選択して、コピー pyautogui.hotkey('ctrl', 'a') pyautogui.hotkey('ctrl', 'c') #すでに存在するExcelワークブックを読み込み、ペーストして保存 wb = openpyxl.load_workbook("./BOS_Data.xlsx") ws = wb['Sheet1'] wc = ws['A1'] pyautogui.hotkey('ctrl', 'v') time.sleep(3) wb.save("./BOS_Data.xlsx")

  • pyhonでweb操作(imageをクリック)

    pythonでweb操作をしたいです。 Chromeでログインするところまではできましたが、 クリックする箇所がimgになっており、どうやってクリックするのかわかりません。 色々調べてみたのですが、xpathを使っても下記のエラーが表示されます。 【エラー内容】 AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath' 【コード】 driver.find_element_by_xpath('//input[@type="image"][@src="/images/btnOrders.gif"]').click() 【画像のElements】 <a href="/Includes/SetMenuType.asp?MenuType=1"><img border="0" src="/images/btnOrders.gif"></a> 【Copy full Path】 /html/body/table/tbody/tr[4]/td[2]/a[1]

  • Python codeで何と書けば良いのか?

    Pythonで株価検索のWebScrapingをSeleniumWeb Driverを使ってCoding しています。 添付の画面で、自動的に”同意する”が選択出来るようにしたいのですが、うまく行きません。私は driver.find_element(By.NAME,"同意します").Click() 等々いろいろ試したのですが、どれもダメでした。 どう記せばよいのでしょうか、教えていただければ有難いです。

  • is not a functionというエラー

    jqueryのスクリプトを書いていたところ $(function () { var wrapper = $("#main"); var wrapperWidth; var blocks = []; NewBlocks(blocks, wrapper.children()); function NewBlocks(blocks, elements) { for (var i = 0; i < elements.length; i++) { var element = elements[i]; var block = new Block(element); blocks.push(block) } } function Block(element) { this.element = element; element.style.margin = "10px"; this.init(); } Block.prototype = { init: function () { this.width = this.element.offsetWidth; this.height = this.element.offsetHeight; } } }); 上記スクリプトを実行すると「this.init is not a function」というエラーが出てしまいます。 一体何をどう間違っているせいでエラーが出るのか、どうかご教授いただけますでしょうか。

  • for文の中でエラーが出てしまいます。

    Perl初心者で、1から勉強始めました。 質問ですが、 #!c:\perl\bin\perl -w use strict; print "Content-type: text/html\n\n"; my %data1 = ( 'id','ID001', 'name','たなか', 'birthday','1970/10/10' ); my %data2 = ( 'id','ID002', 'name','すずき', 'birthday','1972/03/21' ); my %person = (\%data1,\%data2); for (my $i=0; $i<@person; $i++) { my %row = %{$person[$i]}; print "$row{'id'}:$row{'name'}($row{'birthday'}生)<br>\n"; } テキスト通りにやっているつもりですが、のforの中でエラーが出てしまいます。見直してもどこが悪いか分かりません。誰かお暇な方教えてください。お願いします。

    • ベストアンサー
    • Perl
  • C# htmlの一部の文字取得

    C#のwebBrowserで表示されているtextを表示させたいです。 htmlが <div class="AAA"> BBB </div> となっており、BBBのtextを取得したい場合、 HtmlElementCollection elem = webBrowser0.Document.GetElementsByTagName("div");   foreach (HtmlElement element in elem)   {    if (element.GetAttribute("class") == "AAA")  {  str = element.InnerText;  } } と、しましたが、上手く取得出来ません。 ご教授頂ければ助かります。

  • JavaScript for文の処理

    JavaScriptでクイズの採点をしたいと思っています。 ↓のスクリプトを書いたのですが 「ページでエラーが発生しました」 という表示がステータスバーにでます。 二問とも一番下の選択肢を選んだ場合 「2点です」とアラートに表示させたいのですがどうしても、うまくいきません。 おそらくfor文内の score + document.myFORM.elements[i].value; このへんがおかしいのだと思うのですが。 どなたか修正方法をお願いします。 <HTML> <HEAD> <script Language="JavaScript"><!-- function GetScore(){ score = 0; for (i=0; i<6; i++) if (document.myFORM.elements[i].checked) score + document.myFORM.elements[i].value; alert(score+"点です"); // --></script> </HEAD> <BODY> <FORM name="myFORM">第一問:あなたは? <BR> <INPUT TYPE="RADIO" NAME="q1" ID="r1"VALUE="0"> <LABEL FOR="r1">引きこもり</LABEL> <BR> <INPUT TYPE="RADIO" NAME="q1" ID="r2" VALUE="1"><LABEL FOR="r2">立てこもり</LABEL> <BR> <INPUT TYPE="RADIO" NAME="q1" ID="r3" VALUE="1"><LABEL FOR="r3">生き残り</LABEL> <BR><BR> 第二問:あなたは? <BR> <INPUT TYPE="RADIO" NAME="q2" ID="r2_1" VALUE="0"><LABEL FOR="r2_1">引きこもり</LABEL> <BR> <INPUT TYPE="RADIO" NAME="q2" ID="r2_2" VALUE="0"><LABEL FOR="r2_2">立てこもり</LABEL> <BR> <INPUT TYPE="RADIO" NAME="q2" ID="r2_3" VALUE="1"><LABEL FOR="r2_3">オタク</LABEL> <BR><BR> <input type="button" value="採点する" onClick="GetScore()"> </FORM> </BODY></HTML>

  • for文

    質問お願い致します。 これのソースのfor文を一つの文にするにはどのように書いたらよいでしょうか? お願い致します。 //指定された文字列が"a"と"b"の両方を含む場合はtrue、なければfalseを返す public class Mondai { public static void main(String[] args) { System.out.println("解答 :" + charBothContain("Habllow")); } public static boolean charBothContain(String str) { boolean answer1 = false; boolean answer2 = false; for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); if (c == 'a') { answer1 = true; break; } } for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); if (c == 'b') { answer2 = true; break; } } return answer1 && answer2; } }

    • ベストアンサー
    • Java
  • Ruby Selenium 要素の待機

    Rubyの初心者でSeleniumを使ってスクレイピングを趣味としてしているものです。 ブラウザはchromeです。 スクレイピングをしたいページで404が数回続き、やっと読み込めるサイトがあるので、404エラーで止まってしまうのである要素が無ければもう一度やり直す、そのようになったら初めからやり直してみる形にしたいと思って色々と調べ試行錯誤をしています。 https://www.qoosky.net/references/58/ を参考に require 'selenium-webdriver' driver = Selenium::WebDriver.for :chrome #chrome のdriverを設定 driver.navigate.to "http://google.com" wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds begin element = wait.until { driver.find_element(:id => "hoge") } ensure driver.quit driver.navigate.to "http://google.com" end id、hogeが無ければもう一度読み直すような形でやってみたのですが全く意味をなしていないようです。 何卒どうかご教授、よろしくお願いします。

    • ベストアンサー
    • Ruby

専門家に質問してみよう