BigData/Python

210719_1(데이터수집하기)

너굴셉 2021. 7. 19. 17:59

도메인을 지정하고 내부 경로를 분석, 수집하는 방법

# 도메인을 지정하고 내부 경로를 분석하는 수집하는 방법

from urllib.request import urlopen
from bs4 import BeautifulSoup
import  datetime
import random
import re


random.seed(datetime.datetime.now()) # 가능하면 중복된 난수가 발생하지 않도록 함

def getLinks(articleUrl):
    html = urlopen("http://en.wikipedia.org"+articleUrl)
    bsObj = BeautifulSoup(html,"html.parser")
    return  bsObj.find("div",{"id":"bodyContent"}).find_all("a",href=re.compile("^(/wiki/)((?!:).)*$"))
                                                  # /wiki/로 시작하고 : 가 없고 문자하나 이상으로 끝나야 한다.

# http://en.wikipedia.org/wiki/Kebin_Bacon 가 처음 여는 사이트가 됨
links = getLinks("/wiki/Kevin_Bacon") # 처음 링크의 갯수를 센다

while len(links) > 0:
    newArticle = links[random.randint(0,len(links)-1)].attrs["href"] # 임의의 링크를 하나 선택함
    print(newArticle)
    links = getLinks(newArticle) # 새로연 문서의 내의 링크 갯수를 센다

사이트 전체 크롤링하기

# 사이트 전체를 크롤링하기

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

pages = set() # set 집합이다. set의 특징 중복을 불허한다.

def getLinks(pageUrl):
    global pages #전역변수 pages를 사용하겠다
    html = urlopen("http://en.wikipedia.org"+pageUrl)
    bsObj = BeautifulSoup(html, "html.parser")
    try:
        print(bsObj.h1.get_text())
        print(bsObj.find(id="mw-content-text").find_all("p")[0])
        print(bsObj.find(id="ca-edit").find("span").find("a").attrs['href'])
    except AttributeError:
        print("찾는 페이지가 없습니다.")

    for link in bsObj.findAll("a", href=re.compile("^(/wiki/)")): # a태그의 href가 /wiki/로 시작되는
        if 'href' in link.attrs:                        # link속성에 href가 있다면
            if link.attrs['href'] not in pages:         # 해당페이지안에 href가 없다면
                newPage = link.attrs['href']            # href로 연결된 페이지를 가져온다.
                print("-----------------------\n"+newPage) # 그 페이지를 검색한다.
                pages.add(newPage)                      # 그것을 전역변수에 등록한다
                getLinks(newPage) #재귀

getLinks("") #지정사이트 루트부터 검색

특정사이트 내부의 링크된 모든 링크목록 수집

# 특정사이트 내부의 링크된 모든
from urllib.parse import urlparse
from urllib.request import urlopen

import urlparser as urlparser
from bs4 import BeautifulSoup
import  datetime
import random
import re


pages = set()
random.seed(datetime.datetime.now())

# 페이지에서 발견된 내부 사이트 링크 목록을 수집
def getInternalLinks(bsObj, includeUrl):
    internalLinks = []
    #Finds all links that begin with a "/"
    for link in bsObj.findAll("a", href=re.compile("^(/|.*"+includeUrl+")")):
        if link.attrs['href'] is not None:
            if link.attrs['href'] not in internalLinks:
                internalLinks.append(link.attrs['href'])
    return internalLinks

# 페이지에서 발견된 외부 사이트 링크를 수집한다.
def getExternalLinks(bsObj, excludeUrl):
    externalLinks = []
    #Finds all links that start with "http" or "www" that do
    #not contain the current URL
    for link in bsObj.findAll("a", href=re.compile("^(http|www)((?!"+excludeUrl+").)*$")):
        if link.attrs['href'] is not None:
            if link.attrs['href'] not in externalLinks:
                externalLinks.append(link.attrs['href'])
    return externalLinks

# 데이터 전처리
def splitAddress(address):
    addressParts = address.replace("http://", "").split("/")
    return addressParts

# 임의의 외부 링크 얻어오기
def getRandomExternalLink(startingPage):
    html = urlopen(startingPage)
    bsObj = BeautifulSoup(html, "html.parser")
    externalLinks = getExternalLinks(bsObj, splitAddress(startingPage)[0])
    if len(externalLinks) == 0:
        internalLinks = getInternalLinks(startingPage)
        return getRandomExternalLink(internalLinks[random.randint(0,
                                  len(internalLinks)-1)])
    else:
        return externalLinks[random.randint(0, len(externalLinks)-1)]


def followExternalOnly(startingSite):
    externalLink = getRandomExternalLink("http://oreilly.com")
    print("Random external link is: "+externalLink)
    followExternalOnly(externalLink) # 임의로 선정된 외부사이트를 시작페이지로
                                      # 재귀로 반복되면 또다른 선택된 임의사이트는 시작페이지로

# 최초의 시작
followExternalOnly('http://oreilly.com')

트위터 검색하기. API토큰키 발급받아와야한다

# 트위터 검색하기
# 패키지 > 모듈 > 클래스 or 함수
from twitter import Twitter, OAuth

t = Twitter(auth=OAuth("Access Token", "Access Token Secret", "Consumer Key", "Consumer Secret"))
pythonTweets = t.search.tweets(q="#python")
print(pythonTweets)

#트위터에서 API 토큰 키를 발급받아와서 위에 넣어서 사용해야한다.

json사용하기

# json 사용하기

import json
jsonString = '{"arrayOfNums":[{"number":0},{"number":1},{"number":2}],' \
             ' "arrayOfFruits":[{"fruit":"apple"},{"fruit":"banana"},{"fruit":"pear"}]}'

jsonObj = json.loads(jsonString)
print(jsonObj.get("arrayOfNums"))
print(jsonObj.get("arrayOfFruits"))
# [{'number': 0}, {'number': 1}, {'number': 2}]
# [{'fruit': 'apple'}, {'fruit': 'banana'}, {'fruit': 'pear'}]

print(jsonObj.get("arrayOfNums")[0])
print(jsonObj.get("arrayOfNums")[0].get("number"))
print(jsonObj.get("arrayOfNums")[1].get("number"))
print(jsonObj.get("arrayOfNums")[2].get("number"))
# {'number': 0}
# 0
# 1
# 2

print(jsonObj.get("arrayOfFruits")[0])
print(jsonObj.get("arrayOfFruits")[0].get("fruit"))
print(jsonObj.get("arrayOfFruits")[1].get("fruit"))
print(jsonObj.get("arrayOfFruits")[2].get("fruit"))
# {'fruit': 'apple'}
# apple
# banana
# pear

scrapy

import scrapy


# 실행방법
# 1. 터미널 창에서 scrapy startproject wikiSpider 명령을 실행하면 아래처럼 만들어진다
# C:\JAVA_BIGDATA\MYWORK_PYTHON\DATA_COLLECTION\WIKISPIDER
# └─wikiSpider
#     └─spiders
# 2. 소스를 작성한다.
#
# 3.실행 명령 : scrapy runspider data_col_0719_06.py(모듈명)


class ArticleSpider(scrapy.Spider):
    name = 'article'
    def start_requests(self):
        urls = ['http://en.wikipedia.org/wiki/Python%28programming_language%29',
                'https://en.wikipedia.org/wiki/Functional_programming',
                'https://en.wikipedia.org/wiki/Monty_Python']
        return [scrapy.Request(url=url, callback=self.parse) for url in urls]

    def parse(self, response):
        url = response.url
        title = response.css('h1:text').extract_first()
        print('url is {}'.format(url))
        print('title is : {}'.format(title))

!중요 미디어 페이지 수집하기

#미디어 페이지 수집하기
import os
from urllib.request import urlretrieve
from urllib.request import urlopen
from bs4 import BeautifulSoup

downloadDirectory = "downloaded" #다운받을 디렉토리명
baseUrl = "http://pythonscraping.com" #기본url

def getAbsoluteUrl(baseUrl, source):
    if source.startswith("http://www."): #소스가 http://www로 시작하면
        url = "http://"+source[11:] #소스의 11번째줄부터 시작하라(http://www를 빼라는뜻)
    elif source.startswith("http://"):
        url = source
    elif source.startswith("https://"):
        url = source
    elif source.startswith("www."):
        url = source[4]
        url = "http://"+source
    else:
        url = baseUrl+"/"+source

    if baseUrl not in url or ".js" in url :
        return None

    return url
def getDownloadPath(baseUrl,absoluteUrl,downloadDirectory):
    path = absoluteUrl.replace("www.","") # www. 제거
    path = path.replace(baseUrl,"") # baseUrl 제거
    path = downloadDirectory+path # 로컬 경로로 바꾼것
    directory = os.path.dirname(path) # 저장 경로의 결정
    # 저장 폴더 생성
    if not os.path.exists(directory):
        os.makedirs(directory) # 폴더가이미있는경우 오류가난다. 중간경로는 자동으로생성
    return path

html = urlopen("http://pythonscraping.com")
bsObj = BeautifulSoup(html,"html.parser")
downloadList = bsObj.findAll(src=True) #이부분을 통해 다운로드받을것을 선택하는것

for download in downloadList:
    fileUrl = getAbsoluteUrl(baseUrl,download["src"])
    if fileUrl is not None:
        print(fileUrl)
        urlretrieve(fileUrl,getDownloadPath(baseUrl,fileUrl,downloadDirectory)) #실제저장

#중요한 예제

cvs 파일로 저장하기

# cvs 파일로 저장하기
import csv
csvFile = open("./test.csv", "w+", newline="")
try:
    writer = csv.writer(csvFile)
    writer.writerow(('number','number plus 2', 'number times 2')) #줄단위로 쓰기
    for i in range(10): # 0~9
        writer.writerow((i,i+2,i*2))
finally:
    csvFile.close()
# test.csv파일이생성되었고 아래는 내용
# number,number plus 2,number times 2
# 0,2,0
# 1,3,2
# 2,4,4
# 3,5,6
# 4,6,8
# 5,7,10
# 6,8,12
# 7,9,14
# 8,10,16
# 9,11,18

# 특정사이트에서 테이블을 읽어서 csv파일로 저장하기
import  csv
from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen("http://en.wikipedia.org/wiki/Comparison_of_text_editors")
bsObj = BeautifulSoup(html,"html.parser")
table = bsObj.findAll("table",{"class":"wikitable"})[0] # 대상이 존재하는지 확인함
rows = table.findAll("tr")
csvFile = open("./mytable.cvs","wt+",newline="",encoding="UTF-8")
writer = csv.writer(csvFile)

try:
    for row in rows:
        csvRow = []
        for cell in row.findAll(['td','th']): # td, th로 찾기
            csvRow.append(cell.get_text()) # csv객체에 추가
            writer.writerow(csvRow) #파일객체에 씀
finally:
    csvFile.close() #자원반납

mysql연결하기

import pymysql

conn = pymysql.connect(host='localhost', port=3306, user='jspuser', password='1234', db='jspdb')
cur = conn.cursor() # sql 실행단위
# cur.execute('use javadb')
cur.execute("select * from member") #preparedStatement와 유사한 역할
print(cur.fetchone()) #하나를 fetch했다. 결과
cur.close()
conn.close()

#여러줄인경우
import pymysql

conn = pymysql.connect(host='localhost', port=3306, user='jspuser', password='1234', db='jspdb')
cur = conn.cursor() # sql 실행단위
# cur.execute('use javadb')
cur.execute("select * from member") #preparedStatement와 유사한 역할
for row in cur.fetchall():
    print(row) #하나를 fetch했다. 결과
cur.close()
conn.close()

#디비에서 읽은것을 csv로 저장하기
import csv
import pymysql

conn = pymysql.connect(host='localhost', port=3306, user='jspuser', password='1234', db='jspdb')
cur = conn.cursor() # sql 실행단위
# cur.execute('use javadb')
cur.execute("select * from member") #preparedStatement와 유사한 역할
csvFile = open("./sqltest.csv", "w+", newline="")
try:
    writer = csv.writer(csvFile)
    for row in cur.fetchall():
        writer.writerow(row) #줄단위로 쓰기
finally:
    csvFile.close()
cur.close()
conn.close()