python에서 웹 스크래핑을 시도해 봤습니다.

15142 단어 Python

개시하다


경량 언어 중perl을 좋아하지만, 왠지 최근python에 관심이 생겼어요.
어쨌든, 학습과 동시에 Yahoo도 시도해 보세요!뉴스의 일람표에서 제목과 본문을 순서대로 다시 써 보았다.
http://news.yahoo.co.jp/list/

컨디션


Python 2.7.11
lxml
requests
selenium
El Capitan이라면 brew에 넣을 수 없습니다.
참조: http://qiita.com/labeneko/items/e3b790e06778900f5719
npm install phantom phantomjs -g

지금 설치


여기
#coding: UTF-8
import json
import lxml.html
import requests
from datetime import datetime
from selenium import webdriver
from time import sleep

#--------------------------------------------------
# WebSpider
class WebSpider:
    def __init__(self, rootUrl):
        self._webDriver = webdriver.PhantomJS()
        self._pageSourceMap = {}
        self._expireTime = (60 * 60) * 1
        self._rootUrl = rootUrl

    def __del__(self):
        del self._webDriver
        self._pageSourceMap.clear()

    def eachContents(self, url, selector, proc):
        for content in self.getContents(url, selector):
            proc(content)

    def getContents(self, url, selector):
        self._releaseCaches()
        if self._hasCachedPage(url) and self._rootUrl != url:
            print "> [!] use cached source: " + url
            return self._pageSourceMap[url][1].cssselect(selector)
        sleep(1)
        self._webDriver.get(url)
        pageSource = lxml.html.fromstring(self._webDriver.page_source)
        self._pageSourceMap[url] = (self._getCurrentUnixTime(), pageSource)
        print "> [i] cached page source: " + url
        return self._pageSourceMap[url][1].cssselect(selector)

    def _hasCachedPage(self, url):
        return self._pageSourceMap.has_key(url)

    def _releaseCaches(self):
        for key, value in self._pageSourceMap.items():
            isExpire = (self._getCurrentUnixTime() - value[0]) >= long(self._expireTime)
            if isExpire:
                print "> [!!!] pop cached source: " + key
                self._pageSourceMap.pop(key, None)

    def _getCurrentUnixTime(self):
        return long(datetime.now().strftime("%s"))

#--------------------------------------------------
# create instance
rootUrl = "http://news.yahoo.co.jp/list/"
webSpider = WebSpider(rootUrl)

#--------------------------------------------------
# eachProcs
def pickUpContents(content):
    webSpider.eachContents(content.attrib["href"], "#link", summaryContents)

def summaryContents(content):
    webSpider.eachContents(content.attrib["href"], "#ym_newsarticle > div.hd > h1", titleContents)
    webSpider.eachContents(content.attrib["href"], "#ym_newsarticle > div.articleMain > div.paragraph > p", mainTextContents)

def titleContents(content):
    print content.text.encode("utf_8")

def mainTextContents(content):
    print lxml.html.tostring(content, encoding="utf-8", method="text")

#--------------------------------------------------
# run
webSpider.eachContents(rootUrl, "#main > div.mainBox > div.backnumber > div.listArea > ul > li > a", pickUpContents)

del webSpider
[i] cached page source: http://news.yahoo.co.jp/pickup/6215860
[!] use cached source: http://headlines.yahoo.co.jp/hl?a=20160927-00000132-spnannex-base
대타·오타니 2루타도... 햄 세이무의 영패소프트웨어 B의 결과를 기다리고 있다
[!] use cached source: http://headlines.yahoo.co.jp/hl?a=20160927-00000132-spnannex-base
◇ 퍼시픽리그 일본햄 0-3 세이부(2016년 9월 27일 세이부 왕자)
우승한 매직넘버를'1'으로 만든 일본 햄팀이 시우에게 0-3으로 졌다.
(약간...)
[i] cached page source: http://news.yahoo.co.jp/pickup/6215858
[i] cached page source: http://headlines.yahoo.co.jp/hl?a=20160927-00000361-oric-ent
미즈키 나이네 콘서트에서 갑자원 천연 잔디가 훼손된 공식 홈페이지에 자초지종을 설명했습니다.
[!] use cached source: http://headlines.yahoo.co.jp/hl?a=20160927-00000361-oric-ent
성우 아티스트 미즈키 나이네가 27일 공식 홈페이지를 업데이트했다.22일 효고·한신갑자원구장에서 열린 물나무 콘서트 이후 일부 언론은 이 구장의 천연 잔디가 파손됐다고 보도했다
(약간...)
...
다 됐습니다.
저기,python 인코딩 보기 싫죠?

간단한 해설


참고 자료: http://qiita.com/beatinaniwa/items/72b777e23ef2390e13f8
하는 일은 간단해, 웹 스파이더.eachContents에서 객체의 URL 및 CSS 선택기 지정
결과 데이터를 eachContents에 중첩
마지막 페이지 (야후의 리스트 페이지에서 두 개의 링크를 찾은 후) 의 제목과 본문을 가져오고 표시합니다.
스스로 말해도 그렇지만 포문으로 쓰면 압도적으로 보기 쉽다고 생각해요.
summaryContents에 설치된 선택기 지정에만
일부 모드의 데이터를 얻을 수 없기 때문에 (애니메이션 등이 삽입된 시스템 등)
모든 데이터를 만들려면 몇 가지 종류의 선택기를 준비해야 한다.
그리고 캐치와 expire를 낭비적으로 넣었는데, 이 인코딩만 하면 의미가 없다.
한층 확장해 몬고 DB에 데이터를 저장하고 MeCab과wordVec2가 함께 놀 수 있도록 다양한 모색 중이다.
끝.

감상


좋은 웹페이지 즐겨찾기