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()