Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

การดึงข้อมูลเว็บด้วย lxml ใน Python

การดึงข้อมูลเว็บ (Web Scraping) ไม่ได้สนใจเฉพาะผู้ชื่นชอบวิทยาการข้อมูล แต่นักศึกษาหรือผู้เรียนที่ต้องการเจาะลึกลงไปในเว็บไซต์ก็สามารถทำได้ Python มีไลบรารีสำหรับ web scraping หลายตัว รวมถึง:

  • Scrapy
  • Urllib
  • BeautifulSoup
  • Selenium
  • Python Requests
  • LXML

บทความนี้จะพูดถึงไลบรารี lxml ของ Python เพื่อดึงข้อมูลจากเว็บเพจ ซึ่งสร้างขึ้นบน libxml2 XML parsing library ที่เขียนด้วย C ทำให้เร็วกว่า Beautiful Soup แต่ก็ยากต่อการติดตั้งบนบางคอมพิวเตอร์ โดยเฉพาะ Windows

การติดตั้งและนำเข้า lxml

ติดตั้ง lxml จากบรรทัดคำสั่งด้วย pip:

pip install lxml

หรือ

conda install -c anaconda lxml

เมื่อติดตั้ง lxml เรียบร้อยแล้ว ให้นำเข้าโมดูล html ซึ่งแปลง HTML จาก lxml:

>> from lxml import html

ดึงซอร์สโค้ดของหน้าที่ต้องการ scrape - มี 2 ทางเลือก: ใช้ไลบรารี python requests หรือ urllib เพื่อสร้างออบเจกต์ lxml HTML element ที่มี HTML ทั้งหมดของหน้า เราจะใช้ requests library เพื่อดาวน์โหลดเนื้อหา HTML ของหน้า

ติดตั้ง python requests:

$ pipenv install requests

ดึงข้อมูลหุ้นจาก Yahoo Finance

สมมติเราต้องการดึงข้อมูลหุ้น/Equity จาก google.finance หรือ yahoo.finance นี่คือสกรีนชอตของ Microsoft Corporation จาก Yahoo Finance:

การดึงข้อมูลเว็บด้วย lxml ใน Python

จาก URL ด้านบน (https://finance.yahoo.com/quote/msft) เราจะดึงฟิลด์ทั้งหมดของหุ้นที่มองเห็นได้ เช่น Previous Close, Open, Bid, Ask, Day's range, 52week range, volume และอื่นๆ

โค้ดด้านล่างทำได้โดยใช้โมดูล lxml ของ Python:

lxml_scrape3.py

from lxml import html
import requests
from time import sleep
import json
import argparse
from collections import OrderedDict
from time import sleep

def parse(ticker):
    url = "https://finance.yahoo.com/quote/%s?p=%s" % (ticker, ticker)
    response = requests.get(url, verify=False)
    print("Parsing %s" % (url))
    sleep(4)
    parser = html.fromstring(response.text)
    summary_table = parser.xpath('//div[contains(@data-test,"summary-table")]//tr')
    summary_data = OrderedDict()
    
    other_details_json_link = "https://query2.finance.yahoo.com/v10/finance/quoteSummary/{0}?formatted=true&lang=en-US®ion=US&modules=summaryProfile%2CfinancialData%2CrecommendationTrend%2CupgradeDowngradeHistory%2Cearnings%2CdefaultKeyStatistics%2CcalendarEvents&corsDomain=finance.yahoo.com".format(ticker)
    
    summary_json_response = requests.get(other_details_json_link)
    
    try:
        json_loaded_summary = json.loads(summary_json_response.text)
        y_Target_Est = json_loaded_summary["quoteSummary"]["result"][0]["financialData"]["targetMeanPrice"]['raw']
        earnings_list = json_loaded_summary["quoteSummary"]["result"][0]["calendarEvents"]['earnings']
        eps = json_loaded_summary["quoteSummary"]["result"][0]["defaultKeyStatistics"]["trailingEps"]['raw']
        datelist = []
        for i in earnings_list['earningsDate']:
            datelist.append(i['fmt'])
        earnings_date = ' to '.join(datelist)
        
        for table_data in summary_table:
            raw_table_key = table_data.xpath('.//td[contains(@class,"C(black)")]//text()')
            raw_table_value = table_data.xpath('.//td[contains(@class,"Ta(end)")]//text()')
            table_key = ''.join(raw_table_key).strip()
            table_value = ''.join(raw_table_value).strip()
            summary_data.update({table_key: table_value})
        
        summary_data.update({'1y Target Est': y_Target_Est, 'EPS (TTM)': eps, 'Earnings Date': earnings_date, 'ticker': ticker, 'url': url})
        return summary_data
    except:
        print("Failed to parse json response")
        return {"error": "Failed to parse json response"}

if __name__ == "__main__":
    argparser = argparse.ArgumentParser()
    argparser.add_argument('ticker', help='')
    args = argparser.parse_args()
    ticker = args.ticker
    print("Fetching data for %s" % (ticker))
    scraped_data = parse(ticker)
    print("Writing data to output file")
    with open('%s-summary.json' % (ticker), 'w') as fp:
        json.dump(scraped_data, fp, indent=4)

เพื่อรันโค้ดข้างต้น ให้พิมพ์คำสั่งด้านล่างในเทอร์มินัล:

c:\Python\Python361>python lxml_scrape3.py MSFT

เมื่อรัน lxml_scrap3.py จะพบว่าไฟล์ .json ถูกสร้างในไดเรกทอรีทำงานปัจจุบัน ชื่อประมาณ "stockName-summary.json" เนื่องจากพยายามดึงฟิลด์ msft (Microsoft) จาก Yahoo Finance ไฟล์จึงถูกสร้างชื่อ "msft-summary.json"

สกรีนชอตของผลลัพธ์ที่ได้:

การดึงข้อมูลเว็บด้วย lxml ใน Python

ดังนั้นเราจึงดึงข้อมูลที่ต้องการทั้งหมดจาก yahoo.finance ของ Microsoft สำเร็จ โดยใช้ lxml และ requests แล้วบันทึกข้อมูลในไฟล์ ซึ่งนำไปใช้แชร์หรือวิเคราะห์การเคลื่อนไหวราคาหุ้น Microsoft ได้