

<https://torahack.com/python-scraping-for-seo/>  
このサイトにあるように、

①検索結果上位サイトのURLを取得  
②title,description等を抜き出す。  
③CSVで出力、ダウンロード

ということをやりたいのですが、うまくいきません。  
下記のGoogle colabファイルを作成実行したところ  
csvファイルが生成されるのですが、中身は空でした。

どなたか、うまくいく方法をご存じの方はおられないでしょうか。

<https://colab.research.google.com/drive/1mW3E74mPd_cIAtkbEn7sudOT4n1s3aT4>

コードは下記です。

[code]

    import requests
    import bs4
    from time import sleep
    import pandas as pd
    from google.colab import files
    import re
    
    # 検索したいキーワードを入力する
    listKeyword = ['犬', '猫']
    
    #　取得したい件数に合わせて数値を変更する
    searchNum = str(2)
    
    response = requests.get('https://www.google.co.jp/search?num='+searchNum+'&q=' + '　'.join(listKeyword))
    response.raise_for_status()
    
    # 取得したHTMLをパースする
    soup = bs4.BeautifulSoup(response.content, "html.parser")
    
    file_prefix = ""
    for word in listKeyword:
      if (file_prefix == ""):
        file_prefix += str(word)
      else:
        file_prefix += "-" + str(word)
    
    fileName = file_prefix+'_Top'+searchNum+'.csv'
    
    # csvファイルのヘッダーを設定する
    df = pd.DataFrame(columns=['URL','Title','Description','metakey'])
    
    sleepCounter = 0
    
    # 検索結果上位サイトのURLを取得する
    for a in soup.select('div#search h3.r a'):
      sleepCounter += 1
      url = re.sub(r'/url\?q=|&sa.*', '',a.get('href'))
    
      try:
        # 取得したURLを読み込む
        search = requests.get(url)
        searchSoup = bs4.BeautifulSoup(search.content, "html.parser")
    
        # タイトルの取得
        titleList = []
        for a in searchSoup.select('title'):
          titleList.append(a.text)     
        title=''
    
        for index,item in enumerate(titleList):
          if index==0:
            title = item
          else:
            title = title + ', ' +item
    
        # ディスクリプションの取得
        descriptionList = []
        for a in searchSoup.select('meta[name="description"]'):
          descriptionList.append(a.get('content'))
        description='No data'
    
        for index,item in enumerate(descriptionList):
          if index==0:
            description = item
          else:
            description = description + ', ' +item
    
        # キーワードの取得
        keywordList = []
        for a in searchSoup.select('meta[name="keywords"]'):
          keywordList.append(a.get('content'))     
        keywords = 'No data'
    
        for index,item in enumerate(keywordList):
          if index==0:
            keywords = item
          else:
            keywords = keyword + ', ' +item
    
      except: #例外処理：サイトを読み込めなかったときにする処理
        print('Failed to read web site.')
    
      # 取得したURL、タイトル、ディスクリプション、キーワードを追加する
      outputRow = [url,title,description,keywords]
      s = pd.Series(outputRow, index=['URL','Title','Description','metakey']) 
      df = df.append(s, ignore_index=True)
    
      # 10件以上検索する場合、秒間リクエスト数の制限を守るため、10件ごとに10秒の待機時間を設ける
      if sleepCounter > 10:
        sleep(10)
        sleepCounter = 0
    
    # csvに出力する
    df.to_csv(fileName, index=False)
    
    # csvをダウンロードする
    files.download(fileName)  
    
[/code]


CC BY-SA 4.0
2019-08-01T19:59:33.840
57114
2022-06-23T06:06:40.717
32946
question
python3 web-scraping beautifulsoup
PythonスクレイピングでGoogle検索画面情報取得


requestsから戻ってきたcontentがfor文で使っているselectにヒットしていないようです。  
Googleのhtmlの様式が変わったことが原因かと思いますが、単純に下記の構文ならばそれっぽいURLを取得できたのでこれを改修して目的を達成できるかもしれません。  
ただしまた様式が変わるとコードが使い物にならなくなりますので、コメントに寄せられた方法を使うことをお勧めします。

[code]

    import requests
    import bs4
    import re
    
    # 検索したいキーワードを入力する
    listKeyword = ['犬', '猫']
    
    #　取得したい件数に合わせて数値を変更する
    searchNum = str(2)
    
    response = requests.get('https://www.google.co.jp/search?num='+searchNum+'&q=' + '　'.join(listKeyword))
    response.raise_for_status()
    soup = bs4.BeautifulSoup(response.content, "html.parser")
    
    # 検索結果上位サイトのURLを取得する(取得できない)
    for a in soup.select('div#search h3.r a'):
        print('aがあればここを通ります')
    
    # 検索結果の'/url'から始まるURLを取得する
    for link in [a.get('href') for a in soup.select('a') if a.get('href').startswith('/url')]:
        url = re.sub(r'/url\?q=|&sa.*', '', link)
        print(url)
    
[/code]


CC BY-SA 4.0
2020-08-05T01:51:53.843
69259
2020-08-05T01:51:53.843
9820
57114
answer