학식 보는 프로그램을 만든다. 일단 C#에서 만들고 안드로이드에서도 만들예정.
저번에 웹툰프로그램 만들면서 html페이지를 전부다 불러오고 특정 코드앞에서 받아오는 형태의 노가다로 파싱해왔는데 html agility pack을 이용해서 효울적으로 만들 수 있었다.
앞으로는 이것을 이용해서 할 생각
1. agility pack을 이용한다.
http://stackoverflow.com/questions/846994/how-to-use-html-agility-pack
대충 정리해놓자면
foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table[@summary='식당정보']"))
label.text += table.InnerText;
라고 한다면 doc의 html 코드중 summary 속성값이 식당정보인 모든 테이블을 가져오고 그 아래의 반복문은 해당테이블의 텍스트값을 라벨에 누적해서 넣는것.
즉 모든테이블의 텍스트가 라벨로 들어가게 된다.
-----설치방법------
Visual 스튜디오에서 프로젝트 우클릭후 Manage Nuget Packages로 들어가서 HtmlAgilityPack을 설치.
agility pack은 xpath를 사용하는데
http://www.w3schools.com/xsl/xpath_examples.asp
여기서 대강 사용법을 알 수 있다. 나중에 정독 예정.
정독해보았는데 //와 /의 사용법만 알아두면 충분한것같다.
일단 야매로 대충 어떤 테이블의 첫 td 값이 중식/석식 일때 그때 2번째 테이블의 값을 알아오는 기능을 구현하였다.
그런데 인코딩문제인지 먼지 계속 외계어로 떠서 인식이 불가능함 현재 연구중...
그 원인을 찾았다. 계속 utf-8로 인코딩했는데 알고보니까 학식페이지 가보면 utf-8이 아니고 euc-kr로 되어있음.
http://stackoverflow.com/questions/14793650/wrong-encoding-with-html-agility-pack
위의 사이트를 들어가면 페이지가 euc-kr로 인코딩 되어있을때 문서 불러오는 방법 나와있음.
구현해야 하는 것들
총 6개의 식당 -> 6개의 Tab
일단 tabcontrol을 사용하여 6개의 식당 탭을 만들었다. 각 탭의 라벨이라던가 버튼의 내용물은 for문을 사용하여 동적 생성함.
여기서 한가지 알아낸점은
첫번째 탭컨트롤에 버튼을 추가하고 두번째 탭컨트롤에 버튼을 추가하는식으로 for문을 돌려서 컨트롤을 추가해야지 탭페이지에 나타나는데
요소는 tabPage1, tabPage2, tabPage3 ... 이라서 for문으로 각 tabPage를 호출하는 방법이 없다.
그러나 tabControl1.TabPages[i].Controls.Add(panels[i, j]); 를 사용하여 각각의 tabPage를 호출하는 방법이 있다.
또한 각각의 탭에는 날짜의 개수만큼의 패널을 동적으로 생성하여 집어넣었다.
즉
1번식당tab
월요일 패널
버튼,버튼,라벨
화요일 패널
버튼,버튼,라벨
.
.
.
토요일 패널
버튼,버튼,라벨
이런형식이다.
각각의 식당마다 월~토 운영하는 날의 개수가 다름
친구에게 물어보았다.
각 1번식당은 금요일까지만 운영하고 2번식당은 토요일까지 운영하는데 이것을 알고있으니까 1번테이블만 5일치 받아오고 2번식당만 6일치 받아오는것이 나은가?
아니면 요일개수를 카운트하는 기능을 넣는것이 나은가?
친구말로는 나중에 바뀔때 수정하기가 귀찮으므로 이럴때는 그냥 카운트하는 기능을 추가하는 것이 맞다고 하였다.
그래서 식당의 개수가 몇개인지 카운트하는 기능을 넣었다.
함수명은 check_number_of_days();
html 코드를 보니까 요일명이 들어가는 td는 테이블 헤더로 해놓았다. 따라서 모든 th의 텍스트중 요일이 들어가는 경우 해당 식당의 날짜개수 카운트를 ++해준다.
예로 2번식당에는 토요일까지 운영하면 월요일, 화요일..., 토요일까지 테이블에 표기가 되므로 위의 코드에 의하여 6이된다.
메뉴 개수가 식당마다 다름
이것은 어떻게 할지 고민했는데 아래에 메뉴표기기능에서 알아서 해결됨.
메뉴의 가격 보여줘야함
이것도 어떻게할지 고민했는데 메뉴표기기능에서 해결함.
운영안하는 날
1번식당은 토요일날 운영을 안하는데 사용자가 토요일로 가면 어떻게 표기할지.
각 식당마다 운영정보 없음을 나타내는 패널을 하나씩 만든다음 운영정보가 없는 날에는 해당 패널을 보여주도록 함.
날짜 표기
오늘 날짜 알려주는 기능과 요일까지 표시해주는 기능.
today = (int)(ClockInfoFromSystem.DayOfWeek + 6) % 7; // 월요일 0 화요일 1 수요일 2 ... 일요일 6 으로 표기되도록함.
label = 오늘 날짜 + (스위치문 위의 today값이 2면 '수'를 붙임, 3이면 '목'을 붙임)
이런형식
날짜 넘어가는 기능
today를 위의 코드로 알맞은 인덱스 값으로 초기화시켜놓고 앞으로가기 버튼을 누르면 1추가 뒤로가기 누르면 1감소
만약 6을 넘어가버리면 다시 0으로 가는 형식.
그리고 인덱스에 해당하는 패널을 보여준다.
move_pre_panel()도 비슷함.
아 헷갈린것은 datetime++; 이아니고 datetime=datetime.AddDays(1);을 해줘야 한다는 점.
now_day는 today를 받아온것이다.
괄호로 영어로 표기된부분 없애자 -> 아직 미구현 구현해야함
영어로 표기해놓은 것은 쓸모없고 자리만 차지해서 없애야한다.
고정된 폼크기
http://ndolson.com/1552
http://stackoverflow.com/questions/13381127/preventing-winform-from-being-maximized
메뉴 보여주기(제일 중요함, 제일 어려움)
제일 어려운 부분이다.
시작하자마자 어디서부터 시작할지 막막했다.
무엇을 탐색하나?
공통 간식 여부
공통찬 여부
아침 점심 저녁인지 점심 저녁인지 여부
월화수목금토인지 월화수목금인지 여부
교직원식당 학생식당 구분 여부
식당정보는 summary 속성의 값이 식당정보다
즉 테이블중 summary속성의 값이 식당정보인 것의 테이블 소스를 가져와서 보여주자.
애초에 html agility pack에 테이블을 가져오는 튜토리얼이 있음
http://stackoverflow.com/questions/9265313/parsing-html-with-htmlagilitypack-and-loading-into-datatable-c-sharp
http://stackoverflow.com/questions/655603/html-agility-pack-parsing-tables
LINQ-to-Objects 라는 되게 손쉬운 방법이 있는듯함
나중에 사용하여 구현해보자
c# 테이블 사용방법
foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table[@summary='식당정보']"))
{
label2.Text += "Found: " + table.Attributes["summary"].Value + "\n";
foreach (HtmlNode row in table.SelectNodes("tr"))
{
foreach (HtmlNode cell in row.SelectNodes("th|td"))
{
label3.Text += "\n"+cell.InnerText;
}
}
}
에서 왜 foreach (HtmlNode row in table.SelectNodes("tr")) tr이 //tr로하면 모든 tr을 다받아오나? // 그냥 foreach문이 그런것
요일몇개까지있나 확인은 if(ths.InnerText.Contains("요일")) 이것으로 요일 들어가는 문자열개수를 카운트함.
http://stackoverflow.com/questions/9199080/how-to-get-the-integer-value-of-day-of-week
labels[i].Text += "\n" + cell.InnerText.Replace(" ", "");
로 원하지않는 문자열 필터링 가능
갑자기 html agility pack 사용중 개체참조리퍼런스 에러가 뜸 해결법 찾는중
이유 : 테이블안에 tr 안에 td가 있으면 //table 하고 바로 td하면 안되고 tr/td 해야 먹힘 !!중요!!
안되는 이유 - 안에 <tr>이랑 \n이 있으면 널이 아님처리되서 그러니까
이제는 마지막 가격이 아래로 내려가부림;;
실행할때 dll파일없이 실행하려면 IlMerge를 사용
'C# > C#' 카테고리의 다른 글
C# - Audio Programmning (1) | 2016.04.25 |
---|---|
C# 콘솔 Output 보기 (0) | 2016.02.24 |
C# 네이버 웹툰 크롤링 프로그램 (1) | 2015.11.16 |