PythonとBeautifulSoupでウェブサイトをスクレイプする方法

インターネット上には、人間が一生で吸収できるよりも多くの情報があります。必要なのは、その情報へのアクセスではなく、情報を収集、整理、分析するためのスケーラブルな方法です。

ウェブスクレイピングが必要です。

Webスクレイピングは自動的にデータを抽出し、簡単に理解できる形式で表示します。このチュートリアルでは、金融市場でのアプリケーションに焦点を当てますが、Webスクレイピングはさまざまな状況で使用できます。

あなたが熱心な投資家である場合、特に必要な情報が複数のWebページにある場合、毎日終値を取得するのは苦痛になる可能性があります。インターネットから株価指数を自動的に取得するウェブスクレイパーを構築することで、データ抽出を容易にします。

入門

シンプルで強力なライブラリであるBeautifulSoupとともに、Pythonをスクレイピング言語として使用します。

  • Macユーザーの場合、PythonはOS Xにプリインストールされています。ターミナルを開いて、と入力しpython --versionます。Pythonのバージョンが2.7.xであることがわかります。
  • Windowsユーザーの場合は、公式WebサイトからPythonをインストールしてください。

次にpip、Pythonのパッケージ管理ツールを使用してBeautifulSoupライブラリを取得する必要があります。

ターミナルで、次のように入力します。

easy_install pip pip install BeautifulSoup4

:上記のコマンドラインを実行できない場合sudoは、各行の前に追加してみてください。

基礎

コードに飛び込む前に、HTMLの基本とスクレイピングのいくつかのルールを理解しましょう。

HTMLタグ

HTMLタグをすでに理解している場合は、この部分をスキップしてください。

First Scraping

Hello World

これは、HTMLWebページの基本的な構文です。すべてがWebページ内のブロックを提供します。

1. :HTML文書には、型宣言で開始する必要があります。

2. HTML文書が間に含まれている

3. HTMLドキュメントのメタ宣言とスクリプト宣言は、との間にあります。

4. HTMLドキュメントの表示部分は、タグの間にあります。

5.タイトルの見出しは、

Original text


使って

タグ。

6.段落は次のように定義されます。

Other useful tags include for hyperlinks,

for tables, for table rows, and
テーブル列用。

また、HTMLタグにはidまたはclass属性が付いている場合があります。id属性は、HTMLタグの一意のIDを指定し、値がHTML文書中でユニークでなければなりません。このclass属性は、同じクラスのHTMLタグに等しいスタイルを定義するために使用されます。これらのIDとクラスを利用して、必要なデータを見つけることができます。

HTMLタグ、ID、およびクラスの詳細については、W3Schoolsチュートリアルを参照してください。

スクレイピングルール

  1. あなたがそれをこする前にあなたはウェブサイトの利用規約をチェックするべきです。データの合法的な使用に関する記述を注意深く読んでください。通常、スクレイプしたデータは商用目的で使用しないでください。
  2. Do not request data from the website too aggressively with your program (also known as spamming), as this may break the website. Make sure your program behaves in a reasonable manner (i.e. acts like a human). One request for one webpage per second is good practice.
  3. The layout of a website may change from time to time, so make sure to revisit the site and rewrite your code as needed

Inspecting the Page

Let’s take one page from the Bloomberg Quote website as an example.

As someone following the stock market, we would like to get the index name (S&P 500) and its price from this page. First, right-click and open your browser’s inspector to inspect the webpage.

Try hovering your cursor on the price and you should be able to see a blue box surrounding it. If you click it, the related HTML will be selected in the browser console.

From the result, we can see that the price is inside a few levels of HTML tags, which is .

Similarly, if you hover and click the name “S&P 500 Index”, it is inside and

.

Now we know the unique location of our data with the help of class tags.

Jump into the Code

Now that we know where our data is, we can start coding our web scraper. Open your text editor now!

First, we need to import all the libraries that we are going to use.

# import libraries import urllib2 from bs4 import BeautifulSoup

Next, declare a variable for the url of the page.

# specify the url quote_page = ‘//www.bloomberg.com/quote/SPX:IND'

Then, make use of the Python urllib2 to get the HTML page of the url declared.

# query the website and return the html to the variable ‘page’ page = urllib2.urlopen(quote_page)

Finally, parse the page into BeautifulSoup format so we can use BeautifulSoup to work on it.

# parse the html using beautiful soup and store in variable `soup` soup = BeautifulSoup(page, ‘html.parser’)

Now we have a variable, soup, containing the HTML of the page. Here’s where we can start coding the part that extracts the data.

Remember the unique layers of our data? BeautifulSoup can help us get into these layers and extract the content with find(). In this case, since the HTML class name is unique on this page, we can simply query .

# Take out the of name and get its value name_box = soup.find(‘h1’, attrs={‘class’: ‘name’})

After we have the tag, we can get the data by getting its text.

name = name_box.text.strip() # strip() is used to remove starting and trailing print name

Similarly, we can get the price too.

# get the index price price_box = soup.find(‘div’, attrs={‘class’:’price’}) price = price_box.text print price

When you run the program, you should be able to see that it prints out the current price of the S&P 500 Index.

Export to Excel CSV

Now that we have the data, it is time to save it. The Excel Comma Separated Format is a nice choice. It can be opened in Excel so you can see the data and process it easily.

But first, we have to import the Python csv module and the datetime module to get the record date. Insert these lines to your code in the import section.

import csv from datetime import datetime

At the bottom of your code, add the code for writing data to a csv file.

# open a csv file with append, so old data will not be erased with open(‘index.csv’, ‘a’) as csv_file: writer = csv.writer(csv_file) writer.writerow([name, price, datetime.now()])

Now if you run your program, you should able to export an index.csv file, which you can then open with Excel, where you should see a line of data.

So if you run this program everyday, you will be able to easily get the S&P 500 Index price without rummaging through the website!

Going Further (Advanced uses)

Multiple Indices

So scraping one index is not enough for you, right? We can try to extract multiple indices at the same time.

First, modify the quote_page into an array of URLs.

quote_page = [‘//www.bloomberg.com/quote/SPX:IND', ‘//www.bloomberg.com/quote/CCMP:IND']

Then we change the data extraction code into a for loop, which will process the URLs one by one and store all the data into a variable data in tuples.

# for loop data = [] for pg in quote_page: # query the website and return the html to the variable ‘page’ page = urllib2.urlopen(pg) # parse the html using beautiful soap and store in variable `soup` soup = BeautifulSoup(page, ‘html.parser’) # Take out the of name and get its value name_box = soup.find(‘h1’, attrs={‘class’: ‘name’}) name = name_box.text.strip() # strip() is used to remove starting and trailing # get the index price price_box = soup.find(‘div’, attrs={‘class’:’price’}) price = price_box.text # save the data in tuple data.append((name, price))

Also, modify the saving section to save data row by row.

# open a csv file with append, so old data will not be erased with open(‘index.csv’, ‘a’) as csv_file: writer = csv.writer(csv_file) # The for loop for name, price in data: writer.writerow([name, price, datetime.now()])

Rerun the program and you should be able to extract two indices at the same time!

Advanced Scraping Techniques

BeautifulSoup is simple and great for small-scale web scraping. But if you are interested in scraping data at a larger scale, you should consider using these other alternatives:

  1. Scrapy, a powerful python scraping framework
  2. Try to integrate your code with some public APIs. The efficiency of data retrieval is much higher than scraping webpages. For example, take a look at Facebook Graph API, which can help you get hidden data which is not shown on Facebook webpages.
  3. Consider using a database backend like MySQL to store your data when it gets too large.

Adopt the DRY Method

DRY stands for “Don’t Repeat Yourself”, try to automate your everyday tasks like this person. Some other fun projects to consider might be keeping track of your Facebook friends’ active time (with their consent of course), or grabbing a list of topics in a forum and trying out natural language processing (which is a hot topic for Artificial Intelligence right now)!

If you have any questions, please feel free to leave a comment below.

References

//www.gregreda.com/2013/03/03/web-scraping-101-with-python/

//www.analyticsvidhya.com/blog/2015/10/beginner-guide-web-scraping-beautiful-soup-python/

This article was originally published on Altitude Labs’ blog and was written by our software engineer, Leonard Mok. Altitude Labs is a software agency that specializes in personalized, mobile-first React apps.