エクセルで複数URLのリンク先から、「在庫状況」「旧定価がいくらか」「ISBNバーコードの番号」という3つの情報を引っ張ってくることはできないでしょうか?
Aの列にあらかじめURLを100個ほど入力し、マクロでもいいですが、リンク先の情報を取得して、B,C,Dの列に引っ張ってくるシステムが欲しいです。
具体的には、このような表を作りたいです。
__A____ ____B__ ____C__ _____D____
URL1 在庫取り寄せ 1500 9784331059685
URL2 品切れ 2500 9784860951344
URL3 現在お取扱いできません 2400 ] 9784899771579
・ ・ ・
・ ・ ・
・ ・ ・
在庫情報はソースでは、
<p class="status_1">在庫取寄せ<br/>
通常1週間以内発送</p><!-- 青 -->
<p class="status_2">品切れ<br/>
ご注文は可能 入荷しない場合あり</p><!-- 赤 -->
<p class="status_3">現在お取扱いできません</p><!-- 灰 -->
の3種類です。URL1でいうと、
旧定価は<p class = "geb_itemDetailTtlKbValue1"><span>旧定価:1,500円+税/BS分類:民俗・風俗・文化・地誌・紀行・他<br />で、
ISBNバーコードの番号は<br />BS(9784331059685/0-04427)</span></p>で囲まれています。
URL1 http://www.bookservice.jp/bs/ItemDetail?cmId=634 …
URL2 http://www.bookservice.jp/bs/ItemDetail?cmId=629 …
URL3 http://www.bookservice.jp/bs/ItemDetail?cmId=615 …
在庫状況は本タイトルの下、旧定価とISBNバーコードは内容紹介の上下にあります。
よろしくお願い致します。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
>相手側のサーバーに負担をかけないようにスリープを1秒入れるなどした方が良いのでしょうか?
それは、難しい相談ですね。今のところは加えなくてもよいと思います。
ダメな時は、Sleepとか関係がなく別途ボタン操作などを加えて、直接閲覧できないようにされてしまいます。このマクロを考える時点で、サイトで禁止されていないことは、こちらで確認しました。最近、有名サイトは、今回のようなWebスクレイピングが禁止している所がありますが、そこは、アクセス数が半端ないということもあります。今回のような内容は、確かにサーバーには負担を掛けていると思います。
※何らかの処置された時には、その対応として、WinHttp を使わずに、InternextExplorer に換えればよいと考えています。ただ、手よりは速くても、かなり遅い反応になってしまいます。たぶん、コードは、今以上にややこしいと想像しています。
スリープは、モジュール画面の一番上(Option Explicitがあれば、その下に入れます)
そして、単位は、
Sleep 1000 '1/1000 秒×1,000 =(1000ms=1秒)
また、画像を参考にしてください。
'Option Explicit
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Sleep の掛ける場所ですが、ループの
Sub Main()
'-中略-
For Each c In Range("A2", Cells(Rows.Count, 1).End(xlUp))
rw = c.Row
If c.Value Like "http://www.bookservice.jp/bs/ItemDetail?cmId=" Then
Call GetHttpLog(c.Value)
Sleep 1000 'ここがよいだろうと思います。
ElseIf c.Value Like "#######" Then
sURL = adrBASE & c.Value
Call GetHttpLog(sURL)
End If
Next
No.2
- 回答日時:
>WinHttp.WinHttpRequestが参照可能なライブラリファイル
これは、WinHttp だけでした。失礼しました。
とりあえず、図を貼り付けますので、それで、探して設定してください。
内容的に、数回程度ならともかく、短い時間に同じサイトに100回もアクセスをする場合には、レイト・バインディングの方法は、お勧めしません。
その書き方は、一応、
Set oWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
となります。ただし、今回、この方法で書き換える、というようなリクエストは、なにとぞご容赦願います。
>「エラーが頻繁に出るようでしたら、ここ以下を外す」というのは、
この文言で、質問されるということは、ほとんど、VBAはお分かりになりませんか?これは、先頭のコメント・ブロック('')が入っている部分を外すということです。
''が先頭にない
On Error GoTo ErrHandler 'エラーが頻繁に出るようでしたら、ここ以下を外す
-中略-(そのまま)
ErrHandler: '上記のErrHandler を外したら、こちらも、End Ifまで外す
If Err() > 0 Then
MsgBox Err.Number & " " & Err.Description
End If
No.1
- 回答日時:
最初に、
http://www.bookservice.jp/
ここを起点ということで解釈しました。
「在庫状況」「旧定価がいくらか」「ISBNバーコードの番号」
これには、書名は不要のようです。
また、サイトの利用規約では、以下のようなスクレイピングの行為は禁止されていないようですが、あまり多用することは、トラブルの元になりますので、十分に余裕を以ってご利用するようにお願いします。
URLを置くのもよいのですが、Id番号の7桁の数字だけでも良いようにしました。
注意:以下のコードでは、レイト・バインディングでもよいのですが、あえて、事前バインディングにしましたので、必ず参照設定をしてください。基本的にエラー処理はしていますが、そうでない場合は、エラートラップ(ErrHandler)を外してください。
また、データは、A2の2行目からを最初としています。
'//標準モジュール
'Option Explicit
Private oWinHttp As WinHttp.WinHttpRequest '参照設定 WinHttp.WinHttpRequest.#.#
Private oHtml As HTMLDocument '参照設定 Microsoft HTML Object Library
Private rw As Long
Sub Main()
Dim c As Range
Dim sURL As String
Const adrBASE As String = "http://www.bookservice.jp/bs/ItemDetail?cmId="
For Each c In Range("A2", Cells(Rows.Count, 1).End(xlUp))
rw = c.Row
If c.Value Like "http://www.bookservice.jp/*" Then
Call GetHttpLog(c.Value)
ElseIf c.Value Like "#######" Then
sURL = adrBASE & c.Value
Call GetHttpLog(sURL)
End If
Next
Set oWinHttp = Nothing
End Sub
Sub GetHttpLog(ByVal strURL As String)
Dim HttpLog As String
Dim Ar As Variant
Dim n As Variant
''On Error GoTo ErrHandler 'エラーが頻繁に出るようでしたら、ここ以下を外す
If oWinHttp Is Nothing Then
Set oWinHttp = New WinHttp.WinHttpRequest '("WinHttp.WinHttpRequest.5.1")
End If
oWinHttp.Open "GET", strURL, False
oWinHttp.Send
If oWinHttp.Status = 200 Then
HttpLog = oWinHttp.ResponseText
Call GetStatus(HttpLog)
Else
MsgBox "アクセスに失敗しました。"
End If
Exit Sub
''ErrHandler: '上記のErrHandler を外したら、こちらも、End Ifまで外す
''If Err() > 0 Then
'' MsgBox Err.Number & " " & Err.Description
''End If
End Sub
Sub GetStatus(HttpLog As String)
Dim iP, iDtl, exPrc, mb
Dim Stk As String, ISBN As String
Set oHtml = New HTMLDocument
oHtml.body.innerHTML = HttpLog
With oHtml
Set mb = .getElementsByClassName("mb10 clearfix")
If mb.Length > 0 Then
Stk = Split(mb(0).innerText, vbCrLf)(0)
End If
Set iP = .getElementsByClassName("geb_itemPropValue2") 'ISBNコード
If iP.Length > 0 Then
ISBN = Split(iP(0).innerText, vbCrLf)(0)
End If
Set iDtl = .getElementsByClassName("geb_itemDetailTtlKbValue1") '旧定価
If iDtl.Length > 0 Then
If InStr(iDtl(0).innerText, "旧定価") > 0 Then
exPrc = Split(iDtl(0).innerText, "/")(0)
exPrc = Replace(exPrc, "旧定価:", "", , , 1)
exPrc = Replace(exPrc, "+税", "", , , 1)
End If
End If
End With
'出力
With ThisWorkbook.ActiveSheet
Application.ScreenUpdating = False
Cells(rw, 2).Value = Stk
Cells(rw, 3).Value = StrConv(exPrc, vbNarrow)
Cells(rw, 4).Value = "'" & Trim(ISBN)
Application.ScreenUpdating = True
End With
End Sub
'///
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- HTML・CSS HTMLソースの質問 3 2022/07/28 13:29
- Visual Basic(VBA) EXCEL関数LOOKUPとFILTERについての質問です 1 2022/12/21 05:53
- HTML・CSS アコーディオンメニューが思うように動作しません。 1 2023/08/20 16:48
- ヤフオク! 関税 詐欺でしょうか?ヤフオク 3 2023/06/25 11:22
- Visual Basic(VBA) VBAで質問があります 1 2022/10/19 10:32
- PHP アコーディオンPHPが上手くいかない 3 2022/07/15 16:29
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- その他(プログラミング・Web制作) pythonのWebスクレイピングでfind_allだとurlがNoneに 4 2022/04/17 18:21
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- Visual Basic(VBA) VBA シート間の転記で、条件の追加コードの書き方について教えて下さい。 13 2023/02/26 09:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルエラー13型が一致しま...
-
実行時エラー 438になった時の...
-
ExcelVBA Range クラスの Page...
-
エクセルVBAで以下のようなコー...
-
プロシージャ名の取得
-
なぜこんな初歩的なVBAのIf文で...
-
エラー1004 PDFの保存ができま...
-
VBAがブレークモードになっ...
-
ADODB.Streamを使用してUTF-8を...
-
INSERT INTOステートメント構文...
-
Outlook.ApplicationをCreateOb...
-
実行時エラー -'-2147417848
-
【Excel VBA】マクロをボタンに...
-
VB6 エラー:438 (InputBoxに値)
-
Invalid procedure call or arg...
-
Application.ActiveInspectorで...
-
vbaのvlookup関数エラー原因を...
-
EXCEL VBAマクロ中断でデバッグ...
-
VBAのコードがエラーになっ...
-
VBA 別シートのセルから、文字...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
実行時エラー 438になった時の...
-
エクセルエラー13型が一致しま...
-
【Excel VBA】マクロをボタンに...
-
なぜこんな初歩的なVBAのIf文で...
-
VBAでのエラー
-
マクロについて教えてください...
-
ExcelVBA Range クラスの Page...
-
実行時エラー3001「引数が間違...
-
VBS実行時エラー オブジェクト...
-
VBAがブレークモードになっ...
-
OLEDB.NETで接続できない
-
プロシージャ名の取得
-
EXCEL VBAマクロ中断でデバッグ...
-
VBSで変数の宣言はできないので...
-
ADODB.Streamを使用してUTF-8を...
-
実行時エラー -'-2147417848
-
AccessVBAでExcelを起動し、罫...
-
VB6+SQL サーバー 2000 で 実行...
-
Outlook.ApplicationをCreateOb...
-
Application.ActiveInspectorで...
おすすめ情報
WinHttp.WinHttpRequestが参照可能なライブラリファイルに無いのですが、どこでダウンロードすればいいのでしょうか?探したが見つからなかったので、レイト・バインディングを一応教えてもらえますか?
また、「エラーが頻繁に出るようでしたら、ここ以下を外す」というのは、
If oWinHttp Is Nothing Then~MsgBox "アクセスに失敗しました。"
までを外すという意味でしょうか?
おかげさまで正常に起動しました。丁寧に画像付きで説明してくださり、ありがとうございました。ところで、相手側のサーバーに負担をかけないようにスリープを1秒入れるなどした方が良いのでしょうか?お察しのとおり、初心者なもので良くわからないのですが、1つのURLを調べるごとに1秒スリープを入れた方が良いですか?また、その場合コード中のどこにSleep(1)を入れたらよいでしょうか?宜しくお願いします。