헤일로 1 - 전쟁의 서막 (2004~2006)

헤일로 하면 역사적이라 생각하는 장면

헤일로 1 전쟁의 서막을 처음 접하게 된 것은 고등학교 2학년 무렵으로 당시 롯데마트의 게임 판매 섹션의 한 구석에 XBOX 콘솔과 헤일로가 시연대로 위치해있었다.
콘솔게임기에 대한 로망이 엄청나던 때라, 체험을 한 번 해보고 너무나도 갖고싶었었다. 당시의 엄청난 그래픽과 컨트롤러로 전해지는 손맛들은 일반적인 PC 게임에서 쉽게 경험할 수 없는 수준이었기 때문이다.

XBOX 콘솔을 사고싶었으나 가격이 가격인만큼 구매할수는 없었는데, 나중에 찾아보니 Windows PC 전용으로도 컨버전 되어서 구매 후 신나게 즐긴 기억이 난다.
대략적인 스토리로는 먼 미래에 코버넌트라는 외계인을 조우하고 엄청난 화력차로 인해 긴급히 피신하다가 헤일로라는 인공 행성에 착륙, 주인공이 헤일로에서 탈출하기까지의 여정을 풀어낸 게임이었다.

 

별거아닌 게임이라고 보았었는데 생각보다도 스토리가 나름 있는 편이었으며 나름 충격과 반전의 스토리라인이 있는 편인지라 아마 지금까지 대충 한 20번 정도 엔딩을 본 기억이 난다.
중간에 플러드가 출몰하는 미션은 분위기도, 소리도 모든 면에서 공포 그 자체였던터라 무서웠다.

 

멀티플레이를 참 많이도 했었다


대학생이 된 2006년에는 자취방에서 헤일로 멀티를 엄청나게 즐겼는데, 당시 PC 멀티는 레더가 있다기보다는 그냥 데스매치 같은 형태로 100킬을 어떤 팀이 먼저 하느냐,를 주로 겨루었는데 이 맵에서 스콜피온이라는 탱크로 학살하기를 아주 좋아했다.
나중에는 유저 커스텀 맵 까지 등장해서 별의별 글리치를 다 쓰기도 했었던 기억이 있다.

멀티플레이의 탈것들은 부서지지 않아서 진짜 운이 좋으면 양학이 가능해서 재밌었던 기억이 난다. 지금도 그 때의 기억이 새록새록할 정도.

이 게임을 계기로 충성스러운 엑전사가 되었...으나, 이는 곧 이어질 헤일로 인피니트 글에서 무참히 짓밟힐 예정이다.

+ 추후 헤일로 1은 발매 10주년 기념 리마스터링이 되었다. 가장 큰 변화로는 기존 구식 모델링의 교체로 인해 조금 더 화려한 효과를 주었다는 점. 거기에 버튼 하나로 클래식 헤일로 1과의 그래픽도 직접 비교가 가능하다는 점에서 좋았었다.

 


헤일로 2 (2013)

 

헤일로 2는 XBOX 전용으로 나온 터라 당시에 출시되자마자 즐길수는 없었다. 추후 헤일로3를 구매한 후에 불법 다운로드판으로 구해서 Windows로 즐기다가, 이후에 XBOX판 헤일로 2를 구매해서 즐긴 케이스.
E3 게임 트레일러가 너무나도 환상적이었던터라 헤일로2를 하지는 못해도 이 영상만은 주기적으로 찾아보면서 헤일로 뽕을 채웠었다. 나중에 구매해서 해보니, E3 트레일러의 장면은 게임 분량의 이유로 삭제가 되었다고.

 

사실 지금봐도 크게 나쁘지는 않은 텍스쳐라 생각하긴 하지만.

트레일러 영상의 그래픽과 게임 그래픽간의 괴리가 너무나도 심해서 현타가 좀 오지게 왔었고 거기에 헤일로 3를 하다가 2를 하게 되어서인지 너프된 그래픽 + 기종의 성능차이로 더더욱 현타가 온 아쉬웠다.
그래도 아비터와 마스터치프간의 교차되는 스토리와 이벤트 컷씬으로 이렇게까지 이야기를 풀어내는 능력에서 아주 놀라웠다. 거기에 헤일로 1에 비해 엄청나게 늘어난 총기들로 더더욱 재밌게 즐긴 편.

기존 헤일로 시리즈들에 비해 게임 볼륨이 엄청 늘어나서 엔딩을 보는데도 FPS 게임 주제에 약 3~40시간이 걸리는 것은 놀라울 따름이었다.

대략적인 스토리로는 헤일로 1의 직후로 헤일로에서 탈출한 주인공 마스터치프와 헤일로를 파괴하는것을 방관했다는 죄목으로 처형을 받게되는 아비터의 시점에서 시작하여 플러드의 지도자인 그레이브 마인드를 통해 헤일로의 진짜 용도르 알게 된다.
이후 헤일로를 발사하려는 코버넌트의 사제단을 배신한 아비터와 마스터치프가 협력하여 헤일로를 또다시 파괴한다는 것이 주된 스토리라인.

진짜 이 그래픽 그대로 실사영화 제대로 만들어줬으면 했는데... 파라마운트 나쁜놈들아

헤일로 1에서는 헤일로(04시설 알파 헤일로) 위의 이야기만을 다룬 반면, 헤일로 2는 헤일로(05시설 델타 헤일로)와 지구를 다루는 편에서 플레이어 입장에서 매우 눈이 즐거웠다.
여담으로, 중간에 ODST 대원과 함께 낙하하는 씬이 있는데 이 씬을 개인적으로 가장 좋아라한다.

+ 추후 헤일로 2는 발매 10주년 기념 리마스터링이 되었다. 비판이 꽤 많았던 헤일로 1 애니버서리와는 달리 실사 컷씬(아주 놀라움)과 헤일로5를 암시하는 컷씬, 보다 원작에 가까운 디테일링 구현 등으로 이질감이 없어져 보기 좋았다.

 


헤일로 3 (2007)


헤일로 3는 내가 군대에 있을 때 출시된 게임이었고, 당시 각종 일간지에서도 비중있게 다뤄질 정도로 인기가 대단했다. 군대에 있을 때까지의 꿈은 게임 개발자였으며 이를 위해 XBOX 360 아케이드를 구매, 100일휴가였나 뭐였나 나와서 헤일로 3만 주구장창 하다 복귀하기까지 했다.

XBOX에 비해 진일보한 그래픽으로 지금 다시 해도 손색없을 정도의 그래픽 품질을 보여주고 있으며 대형 전투씬들이 군데군데 배치되어있어 더더욱 즐겁게 했었다.
아직도 기억에 남는 장면은 여명호(Forward Unto Dawn)가 지상착륙을 하는 장면과 펠리컨 건쉽이 폭격을 하는 장면.

 

지금봐도 크게 나쁘지 않을 그래픽

대략적인 스토리로는 헤일로 2 에서 탐지된 아크의 존재가 알고보니 지구에 존재하고 있다는 내용으로 끝맺게 되는데 이를 위해 모두가 지구로 모이고, 지구에서는 아비터 엘리트 연합과 인간이 손을 잡고 침공한 플러드를 구제하는 와중에 아크를 통해 들어가 제작중인 08시설 헤일로를 파괴한다는 내용.
이후 헤일로 파괴의 후폭풍으로 타고 온 함선인 여명호마저 반쪽이 되며 주인공 마스터치프는 동면중인 상태로 우주에서 떠돌게 되는 운명에 처해진다.

 

어제의 적은 오늘의 아군

가장 좋아하는 무기는 당연히 배틀라이플과 코버넌트 카빈이지만, 중력해머 또한 손맛이 좋아 자주 사용했다.
아쉽게도 헤일로 2, 3에서는 돈이 없는 관계로 라이브 서비스에 미가입, 멀티플레이를 즐겨본 적이 없다는 점이다.
그리고 가장 좋아하는 씬은 아비터와 마스터치프가 한 편이 되어 서로의 등을 내어주던 그 씬이다.

 

헤일로 3 ODST (2009)

 

군대 전역 한 이후, 헤일로 3 ODST라는 게임이 신규로 출시되었다. 
대략적인 스토리로는 헤일로 2의 직후, 뉴 몸바사에서 코버넌트 함선이 슬립 스페이스를 통해 헤일로를 출발하는데, 이 때 여명호가 같이 껴들어간다. UNSC는 딱 이 시점에 지상으로 ODST 대원을 투입하는데 이 임무에 대해서는 극비인 상황.

스파르탄이 등장하지 않는 외전격인 작품인데, 사실 스킨만 ODST 대원일 뿐 큰 틀에서는 스파르탄과 차이가 없다. 그래봤자 쉴드라거나 넘어진 탈것들을 되세울 수 없다는 것 정도?
주인공 루키가 스토리를 진행하면서 옴니버스적인 성격으로 팀원들의 이야기를 듣는 방식인데, 중간중간 남아있는 오디오로그를 모두 모아야 비로소 이 이야기의 전말과 숨겨진 스토리가 무엇인지 제대로 알 수 있었다.

 

설정 이미지일 뿐이지만 개박살난 뉴 몸바사의 음울한 분위기가 게임 내에서 제대로 표현된다.


극 초반부의 ODST 드랍포드 강하씬과 후반부의 스토리는 정말 놀라울 따름이며 기존 헤일로 시리즈와 다르게 조용하고 우울하게 진행되는 게임 내 분위기는 이 분위기대로 잠입액션 하나 만들어주면 좋을텐데, 하는 환상을 갖기 충분했다.
지금도 OST를 듣는 게임 중 하나.

 

여담이지만 헤일로 시리즈의 트레일러 중, 가장 마음에 들었던 트레일러가 헤일로 3 ODST 에서 나오기도 했었다. 이건 뭐 지극히 개인적인 취향이지만.


헤일로 리치 (2010)

 

명실상부 헤일로 시리즈의 팬이라면 하나같이 손꼽는 명작중의 명작. 기존 헤일로 시리즈의 제작자 번지소프트가 만든 마지막 헤일로 시리즈이자, 앞으로 다시는 나오지 않을 헤일로 시리즈의 최고봉.

 


헤일로 1 스토리의 시작점 직전의 이야기로 소설에서나 나온 '리치행성'의 이야기가 주를 이룬다. 인류의 첫 코버넌트 조우를 그린 게임으로 외계인을 만난 후 급박하게 돌아가는 상황과 최후반부의 엔딩씬은 그야말로 남자라면 눈물을 쏟아버리지 않을까 싶을 정도.
컷씬으로만 존재하던 코버넌트 함선의 유리화 공격이라거나 함께 동고동락한 스파르탄 전우들의 전사, 대형 전투씬 등 게임을 진행하는 내내 지루할 틈이 전혀 없는 게임이기도 했다.

 

정말이지 스파르탄 노블팀의 희생이란..


스토리의 완결성 측면에서도 이보다 더 완벽할 수 있을까, 싶은 게임.


아직도 잊을만하면 시작해서 엔딩을 보는 게임이기도 하다. 4K 업그레이드가 된 후에는 눈이 더 호강하느라 재미진 게임. 외계에 대한 공포감을 자극하기 위해 일부러 '코버넌트의 더빙'을 하지 않았다는 점에서 제작진들의 노력이 엿보이기도 했다.


앞으로 343 인더스트리가 만드는 헤일로에서 이정도의 완벽함을 볼 수 있을까... 이젠 그럴일이 없겠지...

블로그 이미지

김생선

세상의 모든것을 어장관리

,

서든어택 (2006)

대학교 입학 후 하숙집에서는 친구들을 잘 만나 다 같이 어울려 놀기를 했었다. 당시에는 손대던 게임이 아주 많았으나, 친구들과 할 때에는 주로 서든어택을 했었다. 웨어하우스라거나 보급창고라거나. 나는 주로 스나이퍼를 도맡아 했었는데 이상하게 서든어택과 같은 PC FPS 게임은 잘 하지를 못하겠으나, 서든어택의 특정 맵에서는 스나이퍼를 참 잘 했었다.
지금은 이름이 기억이 나지 않던, 버스가 있는 다리 위 맵에서는 쐈다 하면 헤드샷이었고 옆에서 이를 보던 친구도 아주 놀라워 할 정도. 오래 한 게임은 아니었으며 이후에는 더 재미난 FPS 게임들(가령 헤일로)이 많아 2006년을 제외하고는 거의 하지를 않았다. 잠깐이지만 재미난 기억이 있던 게임이다.

 

당시에는 이런 플래시게임 같은 그래픽이 뭐가 재밌고 인기가 많았는지 도저히 이해가 가지 않았지만, 나이를 먹고 세상을 보는 시각이 조금 넓어지니 오히려 이러한 라이트한 게임이 인기가 많은것은 당연하다는것을 알게 되기도 했다. 

 

마비노기 영웅전 (2010 ~ 2012)

방패와 방어구 염색한다고 돈을 얼마나 들였는지...

군대 전역 후, 우리나라에도 드디어 콘솔게임같은 PC 게임이 나온다는 이야기로 흥했었다. 몬스터 헌터(당시에는 알지 못했던 게임)와 같은 부위파괴니 재료수급 및 제작이니 하는 말들로 세일포인트를 잡았던 기억이 있었다.
베타테스트에도 참가했고, 극초기부터 플레이를 한 만큼 이후 업데이트를 통한 호불호가 극명하게 갈리던 게임이었다. 게임 초반에는 리얼리티를 강조하겠다며 포션 1개당 4모금으로 나눠마실수 있으며 한 번 마신 포션은 상할 수 있으니 재사용이 불가하다거나 사용한 무기/방어구는 더러워지며 세척하기 전 까지는 깨끗해지지 않는다,와 같은 별 쓸모없는 설정들이 잔뜩 있었다.

데브캣에서 만든 게임이니만큼 적어도 그 당시의 시즌1 에피소드 까지는 스토리라인이 아주 탄탄하여 몰입감이 좋았으나, 시즌2가 업데이트 되면서부터는 도저히 몰입이 되지 않는 스토리로 게임이 망해가기 시작했다.
내가 주로 하던 캐릭터는 피오나 - 검방패, 린 - 창을 주로 했었는데 소형방패의 검오나는 헤비스텐더 스킬 발동시 이펙트와 소리, 밀려나가는 모션까지 너무나도 완벽해서 손맛이 좋았었다. 추후에 업데이트된 엘쿨루스 보스전에서 15인 파티원 중 14명이 전사했을 때 엘쿨루스의 가드불가 패턴을 제외한 나머지 패턴들을 모두 막아내며 파티원들의 환호를 받았던 것은 아직도 기억이 생생했다.

 

저 무기가 그 15강 그 무기 같은데

이후 게임을 접겠다며 10강짜리 주무기를 강화해서 폭발시키려고 계획했으나, 15강까지 업글이 되어버려서 강제로 접지못하고 써버렸던 일도 있었다. 그런데 이 계정은 해킹을 당했고...
친구가 엘쿨루스의 눈물을 먹으면서 돈을 줄테니 복귀하라고 꼬셨고, 새로 시작하면서 린 - 창무기로 새로 시작하게 되었다. 이 때 부터는 키보드 마우스 조합으로 플레이 하지 않고, XBOX 360 게임패드를 매핑해서 플레이를 주로 했었다.

게임 초반에는 위에서 언급한 불합리한 게임 시스템은 많이 개선되었으나, 난이도가 어렵다는 이야기가 많았는지, 보스몬스터들의 난이도들 또한 대폭 하락한 적이 있었다. 놀 치프틴이라거나 고블린 족장이라거나. 창을 통한 부위파괴도 있었지만 캐릭터들의 특수 공격 모션을 통한 부위파괴도 존재했다.
열심히 한 게임에 속하긴 한데, 이상하게 컨트롤이 구려서 그 흔한 콜라곰 버스도 남들 태워줄 실력이 되지 않았다 -_-;

이 게임을 하면서 소름돋았던 부분이 몇 포인트 존재하는데, 다크나이트 업데이트를 통한 다크나이트 변신씬이라거나 에피소드 중 '우리 모두를 죽여도', 마지막 에피소드인 카단의 흑화와 '여신강림' 이 부분이 가장 기억에 많이 남고 좋았던 시나리오 중 하나였다. 그런데 뭐, 지금은 그냥 야겜이 다 되어버린게 참으로 슬프지.


블레이드 앤 소울 (2012)

포화란 캐릭터 디자인은 지금 봐도 촌스럽지 않은 것 같다.

이후에 다 같이 마비노기를 하던 친구들이 건너가 NC의 블레이드 앤 소울을 시작하게 되었다. 당시의 NC는 지금처럼 흑화하기 전의 NC로 블소 또한 월 정액제 컨텐츠로 시작한 게임이었다.


당시 기준으로 그래픽이 매우 화려했고, 우리나라에서 보기 드문 무협 소재의 게임으로 아주 재밌게 했었...으나, TV의 유행어들을 NPC 대사로 고대로 박아넣어서 촌스러움을 떨칠 수 없기도 했었고, 정액요금제의 가격이 상당해서 결국 정식서비스를 시작한 이후에는 친구들 모두 리타이어하게 된 계기가 되었다.
그래도 나름 재밌었고, 핏빛 상어항의 포화란 캐릭터는 참 잘 만들어진 것 같은데, 지금은 어쩌다가 저렇게 게임이 망해버렸는지 참으로 아쉬울 뿐.


포화란 피규어 갖고싶다....

 

 

디아블로 3 (2012)

얼마나 지랄맞았으면 이런 짤도 나왔을까.

디아블로 시리즈의 최신작이 오래간만에 공개되면서 왕십리였나 어디에서 밤새도록 대기 후 구매한다느니, 연예인이 갖고싶다는 글을 쓰니 팬들이 조공을 바쳤네 하는 기사로 온통 들썩였을 때 였다.
원래 디아블로2를 좋아했다가, 공개된 디아블로3의 그래픽이 영 마음에 안들어서 안하려다 블소의 개같이 망함 후에 할 게임이 없어 구매 후 하게 되었다.

남들보다 대충 2주 정도 느리게 시작을 했었는데 리얼한 컷씬들과 디아블로 시리즈 특유의 파밍은 너무나도 재밌었다. 추후 만렙을 찍고나서부터는 본격 파밍에 들어갔었는데, 불합리한 엘리트 몬스터들의 스킬들과 내가 주로 플레이하던 악마사냥꾼의 너프로 인해 오래하지 않고 접었던 게임이기도 했다.
사실 디아블로2 처럼 적당히 어두침침하게 나왔으면 더없이 좋았으련만, 지나치게 밝은 톤으로 화사하게 나와버리니 이게 디아블로가 맞나? 하는 생각은 줄기차게 들긴 했었다. 뭐 시즌업데이트가 계속 진행되면서 많이 나아졌다곤 하지만, 그건 그거고 이건 이거인거지.

블로그 이미지

김생선

세상의 모든것을 어장관리

,

아본의 엘시노 소드 앞에서. 저 엘시노 소드가 참 갖고싶었는데.

 

마비노기는 내 게임 인생 중 가장 오래한 PC 온라인 게임이라고 봐도 무방할 정도이다.

 

 


고2때 TV에서 틀어준 CF를 시작으로 마비노기를 시작했으며, 한창 디씨인사이드를 많이 했었던지라 디씨 마갤에 상주하면서 군대가기 직전 까지, 그리고 군대를 다녀오고 사회인이 되어서까지 오래오래 즐긴 게임이다.
마비노기의 흥망성쇠를 다 알고 있다고 한다면 당연히 거짓이겠지만, 나름 찬란했던 시절과 암흑기로 넘어가던 시절까지 즐긴 편이니 이정도면 상당히 오래한거는 맞다.

 

이 넓은 대륙을 엘로드 들고 걸어다닌 적도 있다;

마비노기를 시작하고 가장 재미있었던 때는 아무래도 새로운 종족인 엘프와 자이언트가 나오기 직전까지였다.
누적레벨과 스킬레벨로 대표되는 초창기의 마비노기는 잦은 환생으로 어빌리티 포인트를 모으고, 스킬을 수련하여 어빌리티 포인트를 소모하여 스킬 레벨업을 이루는 방식으로 되어있으며 장비들을 직접 제작, 숙련도를 통한 개조, 인챈트로 대표되는 장비 시스템과 극초기에만 호황(?)이었던 아르바이트, 나름 체계적인 시나리오 등으로 내 입맛에 쏙 들었었다.

 

축포 한가방 꽉채우는것은 국롤

성당 아르바이트를 하게 되면 축복의 포션을 구할 수 있었고 이 축포를 사용하게 되면 해당 장비의 내구도 소모량이 줄어드는 효과가 있었는데, 장비의 수리확률이 일부를 제외하고는 100%가 아니다보니 축포는 게임 내 필수적인 아이템이나 다름없었다.
쪼렙때는 부캐의 부캐를 돌려가며 축포 노가다를 했었고, 이걸 팔아치우면서 돈을 벌기도 했었다.
디씨 마갤러들을 만나며 장비도 허접하게 맞추기를 시작했고, 군대를 다녀오고나서는 아예 친구가 되었고 이 친구들은 10년이 지난 지금까지도 안부인사를 묻는 관계가 되었다. 게임에서 친구를 실제로 사귀다니, 아주 놀라울 정도.

 

한창 열심히 할 때의 스킬

마비노기는 직업 이라는 개념이 없었으며 (추후에는 재능 뭐시기 업데이트를 통해 직업적인 개념이 정립되긴 했다) 근접 스킬 / 활 스킬 / 마법 스킬 등 어떤것을 우선시하여 스킬레벨을 올리느냐에 따라 직업으로서의 개념이 존재했다.
거기에 스텟을 보정해주는 스킬들로는 생활 스킬이 있었는데 그 중에서 방직 스킬과 제련 스킬은 진짜 토나올 정도로 난이도가 빡세고 노가다도 엄청났던 기억이 난다. 뭐, 요즘은 엄청 쉬워졌다지만.

 

친구들과 아본 던전을 돌 때.

가장 기억에 남는 던전은 이멘마하의 룬다던전으로 몽환적인 BGM이 아주 인상적이었다. 극초기(이리아가 나오기 전)에는 그저 저승에 가서 빨간구슬 던전 노가다를 뛰는것이 최고라곤 했는데 그럴바에야 사람들 틈에 껴서 알비 상급 던전이나 마스 상급 심심하면 페카 던전에 꼽사리 껴서 가는 것이 그렇게나 재밌을수가 없었다.
대학생이 되고 나서는 월정액권을 결제하며 게임을 즐겼지만, 용돈이 그마저도 여의치 않을 때에는 일일 2시간 플레이를 수행한 후, 접속이 끊기기 직전에 던전에 쳐박아두고 아는 사람들과 수다떠는것이 그나마 유일한 낙이었다.
이 당시의 이 행동을 '나과장이 잡으러 온다'는 식으로 밈화 해서 이야기 했던 것도 있었다.

 

이 펫은 1살에 60레벨을 달성했다. 가히 최강의 펫.

이후 이리아가 업데이트 되면서 새로운 종족인 자이언트와 엘프가 새로 생겼고 별의별 스킬과 펫들이 본격적으로 대두되기 시작했다.
엘프는 활 스킬에 이점이 있는 종족이었고, 자이언트는 근접공격에 이점이 있는 종족이었다. 인간의 양손검은 자이언트에게 한손검으로 취급된다거나, 엘프는 걸음걸이가 빠르며 활 공격이 두 발씩 나간다거나 하는 소소한 차이점이 존재했다.

 

반신화

이 즈음부터는 본격적으로 마비노기 유저들에게서 돈을 빨아먹었던 때로, 어마어마하게 넓은 이리아 대륙을 그냥 다니기가 어려우니 날아다니는 펫이나 말 펫들이 엄청나게 출시되었다. 거기에 나중에는 공격력이 상당한 펫들 뿐만 아니라, 소환시 경직 공격을 주는 펫 까지 등장하여 이 펫이 없으면 파티에 안껴줄 정도의 밸런스파괴를 불러일으키기도 했다.
그리고 이리아 업데이트를 시작으로 마비노기의 시나리오는 산으로 가기 시작했고, 결국 나중에는 대체 뭔소릴 씨부리는것인지 도저히 이해하기 어려운 스토리들이 연이어 나오기도 했다. 그래서 브류나크가 어쨌고 반신이 어쨌고... 그래서 세익스피어는 왜 나온거더라? 아직도 그들의 관계는 이해할수가 없네.

초기의 G1~G3의 스토리는 각각의 연결고리와 반전 스토리가 숨어있는 등 치밀하고 탄탄한 스토리가 아주 좋았으나 후반부로 갈 수록 개연성도 떨어지고 설득력도 떨어지는 스토리들로 그냥 보상이나 구하려는 메인 스토리가 된 것이 참으로 아쉽다.

 

초기에는 빨구던전이 있었다면, 내가 접기 직전까지는 탈틴의 정찰하드가 있었다. 탈틴이라는 지역의 퀘스트(?) 중에, 정찰병 구출이라는 몬스터 리젠 퀘스트가 있었는데 여기 하드 난이도가 빠른 시간 내에 끝나고 보상도 상당히 좋은(우아한 건틀렛)편이었다. 허구언날 여기서 주구장창 수다떨며 놀기도 했던 아련한 추억이 있다.

 

그나마 이정도가 내가 가장 잘 꾸민거라거나..

나름 꾸미기가 메인 컨텐츠인만큼 귀엽고 아기자기한 그래픽들 사이에서 여캐 비율이 극도로 높은 편이었으나 나는 그러한 고만고만한 씹덕취향이 너무나도 내 스타일이 아니라서 대놓고 신기하게 생긴(?) 캐릭터들을 주로 만들었다. 또는 예쁜 반짝이 염색약들 보다는 어디서 아무도 쓰지 않는 염색약들을 잔뜩 모아다가 모든 파트에 발라서 나이트 사이키 조명과도 같은 모습으로 다닌다거나. 오히려 이러한 점이 내 마음에 들었을지도 모르겠다.

게임을 접기 직전에는 온갖 추악한 업데이트가 많았는데, 대놓고 파티플을 유도하는 교역이라거나 돈벌어먹을 상술로 대표되는 각종 캐쉬템들이 그러했다.
특히 세공이라는 것이 나왔을 때에는 사회적인 이슈가 될 정도로 문제가 많고 게임 내에서의 밸런스도 상당히 문제였을듯. 이후 게임을 접어서 지인을 통해 마비노기의 근황을 엿듣고는 하는데, 내가 했을 때와는 전혀 다른 게임이 되어버려서 대체 누굴 위한 게임인가, 싶을정도이긴 하다.
그나마 이제는 그 구닥다리 플라나리아 엔진인가 플레이오네 엔진을 언리얼로 바꾼다고 하니, 이제는 좀 더 나은 게임 환경이 되지 않을까 싶긴 하다.

말은 이렇게 했어도 게임 인생 중 가장 재미있게 즐겼던 게임임에는 틀림없다.
길드 정모도 몇 번이나 있었고, 지금도 연락하고 결혼식에 와줄 친구들을 만들었다거나 어디가서 술안주로 게임이야기를 하면 빠질 수 없는 추억을 만들어줬으니까.
지금 생각해보면 저런 게임을 다시는 못하겠지 싶긴 하다. 이 즈음부터, 우리나라의 게임 대세는 MMORPG가 아니라 한두시간 안에 끝날만한 게임들 위주로 대세가 기울기도 했고 말이다.

블로그 이미지

김생선

세상의 모든것을 어장관리

,

개발하는데 java 배치로 Windows Powershell을 파라미터 방식으로 호출할 일이 생겼다. 일단 powershell Script 코드는 다음과 같다.

 

1
2
echo 'TEST-1' $test
echo 'TEST-2' $userid
cs

대충 파라미터 두 개( test/userid)를 받아 echo로 찍어주는건데 기타 하위에는 물론 Azure Portal과의 통신이 있긴 하다. 근데 그게 중요한 것은 아니니까.

아무튼, java에서 파워쉘을 호출하는 소스코드는 다음과 같다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//중략
 
final Runtime rt = Runtime.getRuntime();
 
//powershell.exe 명령어를 통해서, 해당 경로의 ps1 파일을 실행함
String commands = String.format("powershell.exe \"F:\\powershell.ps1  ");
 
Process proc = null;
String s = null;
 
// PowerShell 명령 시도 및 메시지 출력
try {
    proc = rt.exec(commands);
 
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream());
    while (( s = stdInput.readLine()) != null ) {
        System.out.println(s);
    }
 
    BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream());
    while (( s = stdError.readLine()) != null ) {
        System.out.println(s);
    }
 
catch (IOException e) {
    e.printStacTrace();
 
}
 
//생략
cs

요기까지는 잘 했는데, 위의 powershell 코드와 같이 parameter를 넘기는 방법을 구글링해보아도 죄다 제각기 방법이 달라서, 츄라이를 해보니 다음과 같은 소스코드로 성공했다.

 

위의 java 소스에서 commands를 다음과 같은 방법으로 변경해주면 된다.

1
2
3
4
5
6
7
//중략
 
String[] arr = {"test_msg" , "test_user"}
//powershell.exe 명령어를 통해서, 해당 경로의 ps1 파일을 실행함
String commands = String.format("powershell.exe \"F:\\powershell.ps1  " + arr[0+ " " + arr[1]);
 
//생략
cs

PowerShell 코드는 다음과 같이 수정해주면 된다.

1
2
3
4
5
$test = $args[0]
$userid = $args[1]
 
echo 'TEST-1' $test
echo 'TEST-2' $userid
cs

java 에서 공백문자열로 구분된 string 값들이 args로 잘 매핑이 된다.

 

테스트를 해보니 해당 ps1(powershell)을 호출할 때 각 String 형태의 parameter(arguments)들을 넘길 때, 그냥 공백문자열로 구분하는 것으로 보인다. 실제로 여러방법으로 테스트 해보니 잘 되기도 하고. 이로써 java로 powershell script를 parameter 포함하여 execute 하는것에 성공했다. 앞으로 근데, 이러한 플젝을 몇번이나 할 지는 모르겠지만 말이다 =_=;;

 

 

java - how pass string array as a parameters to a powershell 

블로그 이미지

김생선

세상의 모든것을 어장관리

,

한컴오피스의 한글파일(hwp)에서 텍스트 추출할 일이 생겼다.

대충 뒤져보니 대단하신 분 께서 한글문서 파서 라이브러리를 만드셨는데, 아직까지도 일부기능에 대해 개선작업을 진행중이신 것 같다.

뭐 표 라거나 그림파일 등에 대해서는 정상동작하지 않는 듯 하지만 나는 텍스트만 추출할 것이기 때문에 당장은 문제없이 사용가능할것으로 보인다.

 

자세한 지원범위는 이 분의 깃으로 들어가보면 될 듯.

https://github.com/neolord0/hwplib

 

GitHub - neolord0/hwplib: hwp library for java

hwp library for java. Contribute to neolord0/hwplib development by creating an account on GitHub.

github.com

아무튼, 대충 임포트하고 대충 써보기로 한다. 생각보다 텍스트 추출이 아주 잘 되어서 다행이다.

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/kr.dogfoot/hwplib -->
<dependency>
  <groupId>kr.dogfoot</groupId>
  <artifactId>hwplib</artifactId>
  <version>1.0.1</version>
</dependency>
cs

이렇게 잡아주고,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
* hwplib hwp document text extraction example
*/
 
import kr.dogfoot.hwplib.object.HWPFile;
import kr.dogfoot.hwplib.reader.HWPReader;
import kr.dogfoot.hwplib.tool.textextractor.TextExtractMethod;
import kr.dogfoot.hwplib.tool.textextractor.TextExtractor;
 
// 중략
 
HWPFile hwpFile;
String hwpText;
try {
    hwpFile = HWPReader.fromFile("/Users/kimfish/DEV/java_workspace/"+"test.hwp");
    hwpText = TextExtractor.extract(hwpFile, TextExtractMethod.InsertControlTextBetweenParagraphText);
 
    System.out.println("===== hwp text extractor =====");
    System.out.println("hwpText = " + hwpText);
catch (Exception e) {
    e.printStackTrace();
cs

이렇게 쓰면 된다. 개꿀

블로그 이미지

김생선

세상의 모든것을 어장관리

,

일전의 포스트와 마찬가지로 pdf 에서도 텍스트를 추출할 일이 생겼다.

당연하겠지만 해당 pdf는 ocr이 된 pdf를 기준으로만 추출이 가능하다.

 

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
<dependency>
  <groupId>org.apache.pdfbox</groupId>
  <artifactId>pdfbox</artifactId>
  <version>2.0.24</version>
</dependency>
cs

이야 1년쯤 전에는 2.0.18 이었는데 그새 버전업했네. 아무튼 maven repository는 이렇게 잡아주고

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* PDFBox library PDF text Extraction Example
*/
 
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
 
// 중략
 
try {
    File file = new File("/Users/kimfish/DEV/java_workspace/"+"/test.pdf");
    PDDocument document;
    document = PDDocument.load(file);
 
    PDFTextStripper s = new PDFTextStripper();
    String content = s.getText(document);
 
    System.out.println("===== docx text extractor =====");
    System.out.println(content); 
catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
cs

이렇게 하면 정상적으로 OCR 처리된 text가 추출된다.

 

 

 

블로그 이미지

김생선

세상의 모든것을 어장관리

,

아주 심플하게, 회사에서 해당 문서규격(xls/xlsx/doc/docx)에 대해 텍스트를 추출하는것이 필요했다. 일전에는 잠깐 해보았는데, 정리된 적이 없었고 이번을 계기로 좀 알게된 몇가지 사실들이 있기에 간단하게 기록해본다.

 

일단 메이븐에서 다음과 같이 라이브러리를 잡아준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-scratchpad</artifactId>
  <version>5.2.2</version>
</dependency>
 
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>5.2.2</version>
</dependency>
 
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>5.2.2</version>
</dependency>
 
cs

 

1. 워드 (doc/docx) 텍스트 추출

워드 2003 이전버전인 doc 와 이후 버전인 docx 를 추출하기 위해서는 두 가지만 기억하면 된다.

HWPFDocument 클래스는 Horrible Word Process Format 의 약자라는 점이며, poi 라이브러리만 상속받는것이 아닌 poi-scratchpad 라이브러리를 같이 상속받아야 한다. 즉, poi dependency만 잡아놓으면 HWPFDocument가 import 되지 않는다!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
* Word 2003 doc File Text Extraction Example
*/
 
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
// 중략
 
try {
    POIFSFileSystem poiFS = new POIFSFileSystem(
        new FileInputStream("/Users/kimfish/DEV/java_workspace/"+"/test.doc"));
    HWPFDocument hwp = new HWPFDocument(poiFS);
    WordExtractor we = new WordExtractor(hwp);
 
    String[] paragraphs = we.getParagraphText();
    System.out.println("===== doc text extractor ======");
    for (int i = 0; i < paragraphs.length; i++) {
        System.out.println(paragraphs[i]);
    }
 
catch (Exception e) {
    System.out.println(e); 
}
cs

 

docx 파일은 XWPFDocument를 import 받으며, docx의 text추출을 위해서는 poi 및 poi-ooxml 라이브러리에 대한 dependency가 필요하다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* Word 2007 docx File Text Extraction Example
*/
 
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
 
// 중략
 
try(
    FileInputStream fis = new FileInputStream
            ("/Users/kimfish/DEV/py_workspace/"+"/test.docx")) {  
    XWPFDocument file   = new XWPFDocument(OPCPackage.open(fis));  
    XWPFWordExtractor ext = new XWPFWordExtractor(file);  
 
    System.out.println("===== docx text extractor ======");
    System.out.println(ext.getText());  
}catch(Exception e) {  
    System.out.println(e);  
}  
cs

 

2. 엑셀 (xls/xlsx) 텍스트 추출

엑셀은 고려할 점이 상당히 많은데 각 셀/로우 별 텍스트 및 쉬트도 있는데다가 수식까지 가지고 있다. 현재는 샘플 토이 프로젝트라 수식이나 셀/로우 구분없이 텍스트만 가져오기를 수행해보았는데 일단 첫 쉬트에서는 잘 가져오고 있는듯. 좀 더 정교한 작업이 필요할 경우엔 공식 document 가 필요할것으로 보인다.

 

엑셀 2003 이전버전인 xls 같은 경우에는 poi Dependency 하나로도 잘 작동한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* Excel 2003 xls File Text Extraction Example
*/
 
import org.apache.poi.hssf.extractor.ExcelExtractor;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
// 중략
 
try (
    FileInputStream fis = new FileInputStream("/Users/kimfish/DEV/java_workspace/"+"/test.xls")) {  
    
    String result = "";
 
    HSSFWorkbook wb = new HSSFWorkbook(fis);
    ExcelExtractor ee = new ExcelExtractor(wb);
    result = ee.getText();    
 
    System.out.println("===== xls text extractor =====");
    System.out.println(result);    
catch (Exception e) {
    //TODO: handle exception
}
cs

 

하지만 엑셀 2007 버전인 xlsx 같은 경우에는 워드2007과 마찬가지로 poi / poi-ooxml dependency 둘 다 필요하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
* Excel 2007 xlsx File Text Extraction Example
*/
 
import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
// 중략
 
try (
    
    FileInputStream fis = new FileInputStream("/Users/kimfish/DEV/py_workspace/"+"/test.xlsx")) {  
                
    // Workbook
    XSSFWorkbook wb = new XSSFWorkbook(fis);
            
    // Text Extraction
    XSSFExcelExtractor extractor = new XSSFExcelExtractor(wb);
    extractor.setFormulasNotResults(true);
    extractor.setIncludeSheetNames(false);
    
    System.out.println("===== xlsx text extractor =====");
    System.out.println( extractor.getText() );
catch (Exception e) {
    //TODO: handle exception
}
cs

 

일단은 이렇게 해서 정상적으로 출력되는것을 확인함. 어휴 poi 하나로 다 해놓든가 의존성을 걸어두던가. 왜 poi / poi-ooxml / poi-scratchpad 이렇게 세 개가 죄다 쪼개져있는지원;;

 

정리

xlsx - poi / poi-ooxml

xls - poi

docx - poi / poi-ooxml

doc - poi / poi-scratchpad

'어장 Develop > 어장 JAVA' 카테고리의 다른 글

[hwplib] hwplib을 이용한 한글파일 텍스트 추출  (1) 2022.07.06
[PDFBox] pdf 텍스트 추출  (0) 2022.07.05
[Tomcat 9.x] JNDI설정  (0) 2022.02.21
[PDFBox] java Image to PDF  (0) 2021.08.24
[xml] RestAPI XML Return (2)  (0) 2021.07.06
블로그 이미지

김생선

세상의 모든것을 어장관리

,

파이썬 개발을 하면서 가장 헷갈리는 개념이 디렉토리 참조법이다. 자바에서는 그냥 대충 import package.directory.fileName; 과 같은 형식으로 지정해주면 바로 가져다 쓸 수 있는데 반해, 파이썬은 그렇지 않은가보다.

 

아무튼 세 가지의 케이스에 대해 정리/적용해보았고 그 내용은 다음과 같다.

 

패키지 구성은 다음과 같은 형식으로 되어있다고 가정한다.

project
⌞ A_folder
   - a_file_1.py
   - a_file_2.py
 B_folder
   - b_file_1.py
   ⌞ C_folder
       - c_file_1.py
   ⌞ D_folder
       - d_file_1.py

1. 동일 경로상의 import

A_folder 내부의 a_file_1.py 에서 a_file_2.py 파일을 import 하기위해서는 다음과 같이 작성한다.

1
from . import a_file_2.py
cs

또는

1
import a_file_2.py
cs

이거는 쉽다.

 

2. 하위 폴더의 import 

B_folder 내부의 b_file_1.py 에서 C_folder 내부의 c_file_1.py를 import 하기 위해서는 다음과 같이 작성한다.

1
from C_folder import c_file_1.py
cs

이정도는 크게 어렵지 않다.

 

3. 상위 폴더의 import

여기서부터 많이 헷갈리게 된다.

C_folder 내부의 c_file_1.py 에서 D_folder 내부의 d_file_1.py를 import 하기 위해서는 꽤 여러가지 방법이 있으나, 일단 내가 해결한 방법을 위주로 작성해본다.

1
2
3
4
import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from D_folder import d_file_1.py
cs

여기에서 os.path.dirname(os.path.abspath( 는 한단계 상위를 의미하며, C_folder의 한단계 상위인 B_folder로 이동함을 의미한다. B_folder 내부에 D_folder가 위치해있으므로, from d_folder 을 해주는 것.

 

마찬가지로 c_file_1.py 에서 A_folder 를 참조하기 위해서는 os.path.dirname(os.path.abspath를 두 번 작성해주면 될 것이다.

 

 

java를 하다와서 그런지, from~ 쪽도 잘 이해가 안갔고 __file__과 같은 옵션네이밍(?)의 정의도 익숙하지 않다. 일단은 해결했으니까, 다음 개발로 넘어가야지...

블로그 이미지

김생선

세상의 모든것을 어장관리

,
1
2
3
4
***** Usage Dev Env *****
= OS - macOS Monterey ver 12.3.1
= IDE - VSCode
= Lang - Python 3.10.4
cs

개발하고나서보니 아래의 내용 모두 다 무쓸모했다.

내가 크롤링하려던 사이트에서 스크립트의 오류인지 뭔지 chromedriver로는 정상적으로 로딩할 수 없었고, firefox를 이용한 geckodriver를 활용하니 단박에 모두 정리가 되었다.

 

아 크롬을 이렇게 버려야하나 ㅡㅡ;

파이썬으로 크롤링 개발을 하는데 요상한 에러가 발생했다. 사실 별 소스코드도 없이 파이썬에 셀레니움, 크롬드라이버를 붙여서 브라우저 하나 띄우는건데 여기서 저런 에러를 만날 줄이야 꿈에도 몰랐다.

 

대충 아래의 소스코드에서 오류가 발생했다.

1
2
3
4
5
6
7
8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
 
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=chrome_options)
driver.get('http://kimfish.co.kr')
driver.quit()
cs

 

그리고 발생오류상황은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
➜  ~ /usr/local/bin/python3 /Users/kimfish/DEV/py_workspace/testChromeDriver.py
Traceback (most recent call last):
  File "/Users/kimfish/DEV/py_workspace/testChromeDriver.py", line 9, in <module>
    driver.get("https://bbs.ruliweb.com")
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 437, in get
    self.execute(Command.GET, {'url': url})
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 425, in execute
    self.error_handler.check_response(response)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py", line 247, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: session deleted because of page crash
from tab crashed
  (Session info: chrome=100.0.4896.88)
Stacktrace:
0   chromedriver                        0x0000000105383c34 chromedriver + 4406324
1   chromedriver                        0x000000010531d290 chromedriver + 3986064
2   chromedriver                        0x0000000104f7e71c chromedriver + 190236
=== 중략 ===
➜  ~ 
cs

 

Message: unknown error: session deleted because from tab crashed 와 같은 오류에 대해 검색을 해보니, 가상머신(대부분 도커)의 /dev/shm 메모리가 부족하다는둥 뭐라는둥 말이 많았는데 난 단순히 내 로컬환경에서 개발을 할 뿐이다 ㅠ

 

그래서 조금 더 찾아보니 chromedriver 호출시, 다음과 같은 옵션을 설정해주면 된다고 한다.

1
2
3
4
5
6
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--headless')
chrome_options.add_argument('--window-size=1420,1080')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--disable-gpu')
cs

적용 후 돌렸다! 그런데도 똑같은 오류가 발생한다!

 

환장하겄다 싶어 옵션을 다 빼보면서 테스트 하다가 결국 원인을 찾기는 했다. 바로, --headless 옵션이 문제였다.

해당 옵션은 UI가 지원되지 않는 서버들을 위해 작동하는 옵션으로 알고 있는데, 내 개발환경에서는 왜 오류가 발생하는지는 아직 잘 모르겠다. 일단 저 옵션을 제외하고는 잘 동작하니까 개발하겠지만... 조금 불안하다. 원인을 알면 해결법도 찾아야하는데.. 으으 

블로그 이미지

김생선

세상의 모든것을 어장관리

,

* M1 MacBookPro macOS Monterey 12.3.1

 

파이썬 + selenium을 이용하여 웹 크롤러를 만드려고 한다.

그전에 셀레니움을 사용하기 위해서는 크롬 디버그모드 활용툴과 같은 개념인 chromedriver를 설치, 사용해야 한다. 설치법은 크게 두 종류로 나뉘는 것으로 보이는데, 'homebrew install'과 '공식홈페이지 다운로드 설치' 두가지의 방법이다.

 

개인적으로는 버전관리가 간편한 homebrew 설치가 좋을것이라 생각한다. 괜히 공식 홈페이지 인스톨 했다가 크롬브라우저 버전업 하면 또 가서 다운받고 압축풀고 할라면 귀찮을듯.

1.  homebrew 로 설치

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
➜  ~ brew install cask chromedriver
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> New Formulae
gops
==> Updated Formulae
Updated 2 formulae.
 
==> Downloading https://chromedriver.storage.googleapis.com/100.0.4896.60/chrome
Already downloaded: /Users/kimfish/Library/Caches/Homebrew/downloads/366342d76a11f7c61ca4b54b8d00cf63f59917eb118f2d9f5745484daa0f8598--chromedriver_mac64_m1.zip
==> Installing Cask chromedriver
==> Linking Binary 'chromedriver' to '/opt/homebrew/bin/chromedriver'
🍺  chromedriver was successfully installed!
==> Downloading https://ghcr.io/v2/homebrew/core/cask/manifests/0.8.8
Already downloaded: /Users/kimfish/Library/Caches/Homebrew/downloads/2b8b007815bfe6179d48bcdcbcce75cc494fd12d6c3dd831e60a05cb50229c7f--cask-0.8.8.bottle_manifest.json
==> Downloading https://ghcr.io/v2/homebrew/core/cask/blobs/sha256:f50a59d4337bc
Already downloaded: /Users/kimfish/Library/Caches/Homebrew/downloads/10cb17e2b53cf4b92c88efd42c0d6dcaf43570a3e7ba65939e070cb79335b3bd--cask--0.8.8.all.bottle.tar.gz
==> Pouring cask--0.8.8.all.bottle.tar.gz
==> Caveats
Emacs Lisp files have been installed to:
  /opt/homebrew/share/emacs/site-lisp/cask
==> Summary
🍺  /opt/homebrew/Cellar/cask/0.8.813 files, 152KB
==> Running `brew cleanup cask`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Caveats
==> cask
Emacs Lisp files have been installed to:
  /opt/homebrew/share/emacs/site-lisp/cask
cs

한 번 지웠다가 재설치한 부분이 있어 로그가 좀 깔끔하지 않은듯 한데, 일단 설치 자체는 어렵지 않다.

그리고 이거 다른 사람들의 블로그에서 잘 다뤄주지 않던 이야기인데, 크롬 브라우저는 워낙에 버전업이 자주되다보니 소스코드가 잘 안돌아간다 싶으면 수시로 브라우저 버전과 크롬드라이버 버전이 일치하는지 확인해야 한다. 그럴 때 쓰는 버전 확인 명령어는 다음과 같다.

 

2. chromedriver 악성소프트웨어 검사

어라? 크롬드라이버 버전확인을 하려 했더니 다음과 같은 오류메시지가 발생하네?

 

‘chromedriver’() Apple에서 악성 소프트웨어가 있는지 확인할 없기 때문에 없습니다.

이는 권한 설정으로 해결할 수 있다. 다음과 같이 수행이 가능하다.

1
2
3
➜  bin git:(stable) pwd
/opt/homebrew/bin
➜  bin git:(stable) xattr -d com.apple.quarantine chromedriver
cs

주의할 점은 xattr -d 명령어 자체가 chromedriver 가 설치되어있는 디렉토리에서 수행해야 한다는 점이다.

brew 로 설치하는 경우에는 /opt/homebrew/bin 디렉토리 내부에 위치한다.

정상적으로 적용이 되어도 별다른 프롬프트가 나오지 않으니 당황하지 말고, 바로 버전 확인 명령어를 작성한다.

1
2
3
4
➜  bin git:(stable) pwd
/opt/homebrew/bin
➜  bin git:(stable) chromedriver -version
ChromeDriver 100.0.4896.60 (6a5d10861ce8de5fce22564658033b43cb7de047-refs/branch-heads/4896@{#875})
cs

현재 브라우저의 버전과 크롬드라이버 버전이 일치하는지는 이렇게 확인하면 된다.

블로그 이미지

김생선

세상의 모든것을 어장관리

,