• ベストアンサー

テキストファイルの中からURLを抽出するには?

VBAで読み込んだテキストファイルからURL部分だけを抽出するにはどうしたらよいでしょうか? InStr関数とMid関数を使って、先頭:http~終わり:空白 or Chr(13)をURLとして切り取っているのですがうまく行きません。 どうも終わり部分の判定が甘いようです。 Sub GetURL(myText)     'テキストからURLを抽出  Dim myText As String  Dim myURL As String   'URL取り込み用  Dim str_pt As Long     '文字列用ポインタ  str_pt = 1          '最初は1文字目から  Do While 1   str_pt = InStr(str_pt, myText, "http")   If str_pt = 0 Then Exit Do   Do While 1    letter = Mid(myText, str_pt, 1)    If letter = Chr(20) Or letter = Chr(13) Then Exit Do    myURL = myURL & letter    str_pt = str_pt + 1   Loop   Debug.Print myURL   myURL = ""  Loop End Sub アドバイスをお願いします!

  • bune
  • お礼率73% (19/26)

質問者が選んだベストアンサー

  • ベストアンサー
noname#223623
noname#223623
回答No.3

#2さんの答えを引き継いで正規表現でやってみました。使えるかどうかは環境によります(IE5.0以降かな?) 以下のコードは読みやすいように行頭に全角スペースが入っています。実際に動かすときは半角にしてください。 Sub test()  Dim teststr As String  teststr = "URL抽出のテスト" & vbCrLf & _        "URLは http://example.com/aaa/bbb/ccc/index.html です。" & vbCrLf & _        "URLは https://example.com/xxx/yyy/zzz/index.php" & _        " または https://example.com/XXX/yyy/zzz/ です。" & vbCrLf & _        "URLはhttpまたはhttps で始まります。"  GetUrl teststr End Sub Sub GetUrl(str)  Dim reg, matches, match  Dim strPat As String  Set reg = CreateObject("VBScript.RegExp")  strPat = "https?:\/\/[0-9a-zA-Z,;:~&=@_'%?+\-/$.!*()]+" ' (1) これが正規表現の検索パターン  reg.Pattern = strPat  reg.Global = True  Set matches = reg.Execute(str) ' マッチしたコレクション  For Each match In matches ' マッチした文字列を一つずつ取り出す   Debug.Print match.Value  Next  Set matches = Nothing  Set reg = Nothing End Sub ==== 結果 =================================== http://example.com/aaa/bbb/ccc/index.html https://example.com/xxx/yyy/zzz/index.php https://example.com/xxx/yyy/zzz/ 正規表現を使ったことないとややこしく見えるかもしれませんが、検索パターンが変わっても(1)を書き換えるだけで済みます。例えばURLには ftp:// とかもあるわけですが、必要になっても(1)を書き換えるだけです。あとの行はまあお決まりなので、この際覚えておくと楽ですよ。正規表現はVB系の話だけではないのでこれから他の言語を覚えるときも役に立ちますしね。 詳しいことは「VBA 正規表現」で検索するといろいろ出てくるので見てください。とりあえず一つだけURL挙げときます。

参考URL:
http://www.officetanaka.net/excel/vba/tips/tips38.htm
bune
質問者

お礼

丁寧にサンプルまで作成していただき感謝!! やはり正規表現を勉強しないと駄目なんですね。 なんとなく面倒で避けてました。 なぜ上記のプログラムで動くのか読みきれていませんが、とりあえずは大助かりです! ありがとうございました。

その他の回答 (2)

回答No.2

VBAではVB Scriptって呼び出せたかな? VBからはやったことがあるが VB Scriptを呼び出せるなら 正規表現が手っ取り早いですね。 $main_text =~ s/(http:\/\/[\w\d\/%#$\&?()~_\.:=+\-!]+)/<A HREF=\"$1\" target=\"_blank\" class=\"main_link\">[リンク]<\/A>/g; $main_text =~ s/(https:\/\/[\w\d\/%#$\&?()~_\.:=+\-!]+)/<A HREF=\"$1\" target=\"_blank\" class=\"main_link\">[リンク]<\/A>/g; 自分が以前Perlで使ったURLをリンクに置換する正規表現です。 VB Scriptは詳しくないのでわかりませんが 一応説明すると正規表現でマッチしたものが $1(特殊変数)に格納される形です。 VB Scriptではそこの所をどう表現して書くのか わかりませんが

bune
質問者

お礼

VB Scriptというのはやったことがないので、ちょっと・・・?Perlも同じく・・・ 我ながら不勉強を痛感します。HTMLのような表記なんですね。 残念ながら理解できませんでしたが、やはり正規表現は避けて通れないらしい・・・? ちょっと勉強してみます。ありがとうございました!

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.1

Chr(32) Or Chr(10) じゃないですか? あと、最後まで見つからない時は Do を抜ける必要があると思います。 2つめの Do のところを Do While str_pt <= Len(myText)   letter = Mid(myText, str_pt, 1)   Select Case letter   Case " ", " ", vbCr, vbLf, vbCrLf: Exit Do   End Select のようにしたら如何でしょう?

bune
質問者

お礼

早速のアドバイスありがとうございます。 >Chr(32) Or Chr(10) じゃないですか? Chr(13)はvbCrのつもりです。Chr(20)は半角スペースですね・・・・この2種類でURLのお尻と判断させています。Chr(10)=vbLfは無視しました。URLの終わりが曖昧なので、抽出が完璧ではありませんでした。(90%以上はOKなのですが) サンプルで書いていただいたように全角のスペースもありえますね!確かに教えていただいたプログラムの方が安全かもしれません。(私のはいかにもアマっぽい・・・) ただ、下記のような書き方のURLが抽出できない点は同じです。 例:下記のURL(http://www.goo.ne.jp)を御参照ください。 このようにURLに続けて文章が来ていると切れ目が判別不能な訳です。ですから「URLには含まれないはずの文字」が知りたいという質問です。 何か一発で抽出するような関数があってもいいように思うのですが・・・・ 最近では漢字(2バイト文字)のURLもありのようですし、決まりごとはないのでしょうか?

関連するQ&A

  • エクセルでURLからタイトルのみを抽出する方法

    URLからタイトルを抽出するマクロについて教えて下さい。 忍者ブログの記事タイトルをURLから抽出しようとしたのですが 文字化けしてしまい全く分かりません。 他のサイトやブログだと普通に抽出出来るのですが・・・ 文字コード?か何かだと思うのですが、原因が分かりません。 ちなみに以下のマクロは、ネット上で検索して見つけたものを そのままコピーして使用しています。 ------------------------------- Public Sub ReadTitle() Dim url As Range Dim Http, buf As String Set Http = CreateObject("MSXML2.XMLHTTP") Set url = Range("A3") Do While (url.Value <> "") Http.Open "GET", url.Value, False Http.Send buf = StrConv(Http.ResponseBody, vbUnicode) 'msgbox buf url.Offset(0, 1).Value = getTitle(buf) Set url = url.Offset(1, 0) Loop Set Http = Nothing End Sub Private Function getTitle(buf As String) As String Dim pos1 As Long, pos2 As Long pos1 = InStr(1, buf, "<title>") If pos1 = 0 Then pos1 = InStr(1, buf, "<TITLE>") If pos1 = 0 Then getTitle = "" Exit Function Else pos2 = InStr(pos1 + 7, buf, "</TITLE>") End If Else pos2 = InStr(pos1 + 7, buf, "</title>") End If getTitle = Mid(buf, pos1 + 7, pos2 - pos1 - 7) End Function ------------------------------ 宜しくお願い致します。

  • VBAでソースから全てのURLを取得したい

    VBAでソースに書いてある全てのURLを取得したいのですが、現状では一部しか取得できません。 文字数制限にでも引っかかっているのでしょうか? どうすれば全てのURLを取得できるのか・・添削して頂けると or ヒントを教えて頂けると助かります。 よろしくお願いします。 (Excel2003を使用) Sub test() Dim objIE As Object Dim objTAG As Object Dim source As String Dim url As String Dim url_start As String Dim url_end As String Dim y As Long url_end = 1 y = 1 Set objIE = CreateObject("InternetExplorer.application") objIE.Visible = False objIE.Navigate "http://dir.yahoo.co.jp/" Do While objIE.Busy = True DoEvents Loop Application.Wait Time:=Now + TimeValue("00:00:03") source = objIE.Document.All(1).Innerhtml Do While y < 10000 url_start = InStr(url_end, source, "<a href=", vbTextCompare) If url_start = 0 Then y = 10000 Else url_end = InStr(url_start, source, ">", vbTextCompare) url = Mid(source, url_start + 9, url_end - url_start - 10) Cells(y, 1).Value = url y = y + 1 End If Loop End Sub

  • vbaの繰り返し処理について

    vbaです。 Sub Test1() Dim Str As String Dim Pnt1 As Long Dim Pnt2 As Long Str = Range("A1") Pnt1 = InStr(Str, "重 http://") If Pnt1 <= 0 Then Exit Sub Pnt2 = InStr(Pnt1, Str, "要") If Pnt2 <= 0 Then Range("B1") = Mid(Str, Pnt1 + 2) Else Range("B1") = Mid(Str, Pnt1 + 2, Pnt2 - (Pnt1 + 2)) End If End Sub という式でA1からA2.A3と下にURLが入っており空欄になるまで同じ処理をしたいのですがどのように変更すれば作動しますでしょうか?

  • URLからタイトルを取得したい!

    エクセルのA列にはURLがずらっとあり、B列にタイトル取得を考えています。 そこで、他の質問者さんのコードを試しました。 その結果、普通のサイトでは問題なく取得できたのですが、 アメーバーブログなどの無料ブログでは、途中で止まってエラーとなってしまうようです。 どこかいけないのでしょうか? Public Sub ReadTitle() Dim url As Range Dim Http, buf As String Set Http = CreateObject("MSXML2.XMLHTTP") Set url = Range("A1") Do While (url.Value <> "") Http.Open "GET", url.Value, False Http.Send buf = StrConv(Http.ResponseBody, vbUnicode) 'msgbox buf url.Offset(0, 1).Value = getTitle(buf) Set url = url.Offset(1, 0) Loop Set Http = Nothing End Sub Private Function getTitle(buf As String) As String Dim pos1 As Long, pos2 As Long pos1 = InStr(1, buf, "<title>") If pos1 = 0 Then pos1 = InStr(1, buf, "<TITLE>") If pos1 = 0 Then getTitle = "" Exit Function Else pos2 = InStr(pos1 + 7, buf, "</TITLE>") End If Else pos2 = InStr(pos1 + 7, buf, "</title>") End If getTitle = Mid(buf, pos1 + 7, pos2 - pos1 - 7) End Function

  • ラベルに全てのテキストデータを読み込みたい

    メモ帳(.txt)に AAAA BBBB CCCC と書いて、これら3行をラベルに表示させたいのです。 Private Sub Form_Load()  Dim myText As String  Open "C:\myFile.txt" For Input As #1 Do While Not EOF(1) Input #1, myText Loop   Close #1  Label1.Caption = myText End Sub 上記のコードだと1行目のAAAAしか表示されません(泣) どなたかご指導宜しくお願いします。

  • エクセルでメタタグを抽出するには?

    すいません、前回質問した者です。 前回の質問では・・・ エクセルシートのB列にURLが並んでいるとして、VBAを使って、C列には「description」D列には「keywords」を抽出したいという質問をしたのですが、参考になる回答がなかったのでもう一度質問します。 以前、私が教えてもらったのは、B列にURLが並んでいて、A列にタイトルを抽出させたものでした。 それが以下になります。 Public Sub ReadTitle() Dim url As Range Dim Http, buf As String Set Http = CreateObject("MSXML2.XMLHTTP") Set url = Range("B1") Do While (url.Value <> "") Http.Open "GET", url.Value, False Http.Send buf = StrConv(Http.ResponseBody, vbUnicode) 'msgbox buf url.Offset(0, -1).Value = getTitle(buf) Set url = url.Offset(1, 0) Loop Set Http = Nothing End Sub Private Function getTitle(buf As String) As String Dim pos1 As Long, pos2 As Long pos1 = InStr(1, buf, "<title>") If pos1 = 0 Then pos1 = InStr(1, buf, "<TITLE>") If pos1 = 0 Then getTitle = "" Exit Function Else pos2 = InStr(pos1 + 7, buf, "</TITLE>") End If Else pos2 = InStr(pos1 + 7, buf, "</title>") End If getTitle = Mid(buf, pos1 + 7, pos2 - pos1 - 7) End Function このような感じでB列にはURLの一覧があるとして、A列にタイトル、C列にdescription D列にkeywordsが抽出できればいいなと考えています。 ちなみに、私にはVBAの知識がまったくありません。とりあず、これだけ出来れば、すごく助かるのですが、どなたか教えていただけないでしょうか?  よろしくお願いします!

  • VBA IEを操作。ファイルダウンロード

    IEを操作して、ファイルをダウンロードしようと思います。 色んなサイトからとってきて、使わせてもらっています。 '---------------------------------IEを開くときに使う Sub IE_OPEN(webUrl As String) Dim objShell Dim writesheet As Worksheet Dim n As Long Dim ID As String, Password As String Set objShell = CreateObject("Shell.Application") Set ie = CreateObject("InternetExplorer.Application") ie.Visible = True ie.Navigate2 webUrl Do While ie.Busy Or ie.readyState <> 4 DoEvents Loop Dim objINPUT Set objINPUT = ie.document.getElementsByTagName("INPUT") 'ループで頭からテキストが 次へ を探す For n = 0 To objINPUT.Length - 1 '※ type="submitボタンなので、.InnerTextじゃなくて、.Valueです ※※注意 If InStr(objINPUT(n).Value, "ログイン") > 0 Then '文字列の中から見つけたら Worksheets("Sheet1").Activate Do While ie.Busy Loop objINPUT(n).Click '見つけたINPUTタグのオブジェクトをクリック Do While ie.Busy Loop Exit For End If Next Set objINPUT = Nothing 'オブジェクト変数解放 End Sub '------------------------------IEを開く(この段階では既に開いてあります。) Private Sub CommandButton1_Click() Do While ie.Busy Or ie.readyState <> 4 DoEvents Loop ie.document.all.ah_ehName.Value = Me.ComboBox1.List(Me.ComboBox1.ListIndex) 'ID Do While ie.Busy Loop Dim objINPUT Dim n As Long Set objINPUT = ie.document.getElementsByTagName("INPUT") For n = 0 To objINPUT.Length - 1 If InStr(objINPUT(n).Value, "ダウンロード") > 0 Then objINPUT(n).Click Do While ie.Busy Loop Exit For End If Next Do While ie.Busy = True DoEvents Loop SendKeys "%S", True'保存 Do While ie.Busy = True DoEvents '何もしないループ(笑) Loop SendKeys "%O",True'ファイルを開く? Do While ie.Busy = True DoEvents Loop 'ie.Quit End Sub ’==================- 面倒なので、IEはPublic変数として モジュールに書いています。 (色んなモジュールを経由する必要があるため、このような手段を取りました) SendKeysをIEに送るというのが出来ずに困っています。 ダウンロードというボタンを押してのダウンロードなので、 ダウンロード用のURL等は分かりません。 Excel2003を使っています。 どうにかSendkeysで出来ないでしょうか? もしくは、もう少し分かりやすい方法は無いでしょうか。 (ファイルを保存しますか?のダイアログの「保存」をクリックして  所定の場所におき、開きたい。 そのまま開くのでもいいけれど、動作が不安定になるのは困る) 以上、よろしくお願い致します。

  • ファイルを読み込んだらVBがフリーズする

    ↓のコードだと、ファイルを読み込んだ時点でVBがフリーズします(平気なファイルも一部ある)。原因と解決法を教えてください。 Private Sub Command1_Click() CommonDialog1.Filter = "テキスト(*.txt)|*.txt|すべて(*.*)|*.*" CommonDialog1.FilterIndex = 1 CommonDialog1.Flags = cdlONFileMustExist CommonDialog1.CancelError = True On Error Resume Next CommonDialog1.ShowOpen If (Err = 0) Then FileRead CommonDialog1.FileName End If On Error GoTo 0 End Sub Private Sub FileRead(FL As String) Dim FileNo As Integer Dim strDAT As String Dim strELM As String Dim pot1 As Integer, pot2 As Integer Dim pDB1 As Integer, pDB2 As Integer FileNo = FreeFile() Open FL For Input As #FileNo While Not EOF(FileNo) Line Input #FileNo, strDAT strDAT = strDAT & ":" pot1 = InStr(strDAT, ":") While pot1 > 0 strELM = Left(strDAT, pot1) pot2 = InStr(strELM, "OPEN") While pot2 > 0 pDB1 = InStr(strELM, Chr(&H22)) If pDB1 > 0 Then '前の『"』の位置 pDB2 = InStr(pDB1 + 1, strELM, Chr(&H22)) If pDB2 > 0 Then RichTextBox1.Text = RichTextBox1.Text & _ Mid(strELM, pDB1 + 1, pDB2 - pDB1 - 1) & vbCrLf End If End If pot2 = InStr(pDB2 + 1, strELM, "OPEN") Wend strDAT = Mid(strDAT, pot1 + 1) pot1 = InStr(strDAT, ":") Wend Wend Close #FileNo End Sub

  • ファイルのパス名をダイアログボックスから選びたい

    下のコードの9行目のOPEN " "の中(ファイルのパス名が入る)を、ダイアログボックスから選べるようにするにはどうすればよいのでしょうか。至急、回答をお願いします。 Private Sub Command1_Click() Dim FileNo As Integer 'ファイル番号 Dim strDAT As String '行データ Dim strELM As String 'マルチステートメントの分解 Dim pot1 As Integer, pot2 As Integer '『:』、『OPEN』の位置 Dim pDB1 As Integer, pDB2 As Integer '『"』の位置(前と後) FileNo = FreeFile Open " " For Input As #FileNo 'ファイルをセットする While Not EOF(FileNo) Line Input #FileNo, strDAT '行データを読み込む strDAT = strDAT & ":" pot1 = InStr(strDAT, ":") 'マルチステートメント対応 While pot1 > 0 strELM = Left(strDAT, pot1) 'マルチステートメントの分解 pot2 = InStr(strELM, "OPEN") 'OPENの位置 While pot2 > 0 pDB1 = InStr(strELM, Chr(&H22)) '『"』の位置 If pDB1 > 0 Then '前の『"』の位置 pDB2 = InStr(pDB1 + 1, strELM, Chr(&H22)) If pDB2 > 0 Then '後ろの『"』があったら RichTextBox1.Text = RichTextBox1.Text & _ Mid(strELM, pDB1 + 1, pDB2 - pDB1 - 1) & vbCrLf End If End If pot2 = InStr(pDB2 + 1, strELM, "OPEN") 'OPENはもうないか Wend '次の命令文 strDAT = Mid(strDAT, pot1 + 1) pot1 = InStr(strDAT, ":") Wend Wend End Sub

  • エクセル内のURLからHPのタイトルを抽出したい

    エクセル内のA列にURLがあるのですが、B列にそのURLのHPのタイトルだけを抽出する方法はありますか? 色々調べて ------------------------------------------ Public Sub ReadTitle() Dim IE Dim url As Range Dim i As Integer Set url = Range("A2") Set IE = CreateObject("InternetExplorer.Application") i = 0 Do While (url.Offset(i, 0).Value <> "") IE.Navigate (url.Offset(i, 0).Value) While IE.busy: Wend While IE.Document.readyState <> "complete": Wend url.Offset(i, 1).Value = IE.Document.Title url.Offset(i, 3).Value = url.Offset(i, 2).Value '前回日付 url.Offset(i, 2).Value = IE.Document.LastModified i = i + 1 Loop End Sub このようなマクロで抽出は出来たのですが、URLは1万件以上あり、PCのスペックの低さのせいか、何時間もかかってしまいます。 もっと早く、タイトルだけを抽出する方法は無いでしょうか? よろしくお願いします。

専門家に質問してみよう