見出し画像

(求む!コードレビュー)スクレイピングしたデータをファイルに保存する

今日は、『独学プログラマー』の第20章 "知識を1つにまとめる"を読んでの疑問点をアウトプットします。

第20章では、ウェブスクレイパーを作成し、Googleニュースをスクレイピングしていきます。取得する文字列を、「html」を含んだURL文字列として画面に出力させます。

「html」を含んだURL文字列は存在しない?

コードを書いていくと以下のようになります。

import urllib.request
from bs4 import BeautifulSoup

class Scraper:
   def __init__(self, site):
       self.site = site

   def scrape(self):
       r = urllib.request.urlopen(self.site)
       html = r.read()
       parser = "html.parser"
       sp = BeautifulSoup(html, parser)
       for tag in sp.find_all("a"):
           url = tag.get("href")
           if url is None:
               continue
           if "html" in url:
               print("\n" + url)

news = 'https://news.google.com/'
Scraper(news).scrape()

実行してみたところ、画面には何も表示されません(T_T)

実際に、Google ChromeでGoogleニュースのサイトを開いて、右クリックの「検証」をクリック。

Elementsを確認すると、どうやら「html」を含んだURL文字列がない模様(←間違いがあればご指摘いただけるとありがたいです)。

そこで、「article」を含んだURL文字列に条件を変更しました。

import urllib.request
from bs4 import BeautifulSoup

class Scraper:
   def __init__(self, site):
       self.site = site

   def scrape(self):
       r = urllib.request.urlopen(self.site)
       html = r.read()
       parser = "html.parser"
       sp = BeautifulSoup(html, parser)
       for tag in sp.find_all("a"):
           url = tag.get("href")
           if url is None:
               continue
           if "article" in url:
               print("\n" + url)

news = 'https://news.google.com/'
Scraper(news).scrape()

そうすると、画面にarticleを含んだ文字列が表示されました。

スクレイピングしたデータをファイルに保存

続いて、章末の「チャレンジ」に挑戦。
先ほど作成したウェブスクレイパーを改造して、ヘッドライン記事をファイルに保存するようにします。

最初に書いたコードがこちら。

import urllib.request
from bs4 import BeautifulSoup

class Scraper:
   def __init__(self, site):
       self.site = site

   def scrape(self):
       r = urllib.request.urlopen(self.site)
       html = r.read()
       parser = "html.parser"
       sp = BeautifulSoup(html, parser)
       for tag in sp.find_all("a"):
           url = tag.get("href")
           if url is None:
               continue
           if "article" in url:
               with open("scrape.txt", "w") as f:
                   f.write(url + "\n")
                   
news = 'https://news.google.com/'
Scraper(news).scrape()

実行結果を確認すると、articleを含んだ文字列が1つしか書き込まれていませんでした。

そこで、ループの外側で、ファイルを一回開くように変更。

import urllib.request
from bs4 import BeautifulSoup

class Scraper:
   def __init__(self, site):
       self.site = site

   def scrape(self):
       r = urllib.request.urlopen(self.site)
       html = r.read()
       parser = "html.parser"
       sp = BeautifulSoup(html, parser)
       with open("scrape.txt", "w") as f:
           for tag in sp.find_all("a"):
               url = tag.get("href")
               if url is None:
                   continue
               if "article" in url:
                   f.write(url + "\n")

news = 'https://news.google.com/'
Scraper(news).scrape()

作成されたファイルを確認すると、articleを含んだURL文字列が1つずつファイルに保存されています。

うーん。
これでいいのかイマイチ確信が持てません。
何かアドバイスをくだされば幸いです。


サポート、本当にありがとうございます。サポートしていただいた金額は、知的サイドハッスルとして取り組んでいる、個人研究の費用に充てさせていただきますね♪