728x90
반응형

* 패키지는 beautifulsoup4 하고 selenium을 다운받으면됨 *

 

필요한 단어의 고유 번호를 가지고 한국수어사전 사이트를 크롤링해서 단어의 영상 주소를 가져오려 했다.

스크래핑은 편하고 많이 쓰이는 BeautifulSoup를 썼다

 

하지만 왼쪽의 페이지 소스처럼 videoarea id안에 밑줄친 주소를 가지고 와야하는데 아무리해도 None값이 나오더라.

그래서 전체 페이지 소스를 긁어와봤는데 videoArea 하부가 텅 비어있었다.

사이트는 동적인 작업으로 영상 주소를 삽입하나 보다,,,,

동적 사이트 크롤링은 한적 없어서 다소 귀찮았지만 우리에게 주어진 자료는 고유번호밖에 없기에 selenium을 사용해서 크롤링을 시도했다.

 

selenium은 동적 페이지 크롤링할 때 정말 많이 쓰이는 라이브러리로 드라이버가 필요하다. 여기서 드라이버는 직접 페이지를 돌려주는 도구다. 즉, 사이트에 직접 들어가야 페이지주소를 가져올수 있기 때문에 시간이 훨.씬. 오래걸린다.

 

일단 드라이버는 chrome web driver, phantom JS, headless 등이 있다고 한다.

내가 참고한 사이트는 크롬 드라이버를 처음으로 안내해줘서 그냥 했다. (근데 크롬 드라이버는 이제 지원이 끝났다고 한다. 지금 사용하는 데에 문제는 없다.)

일단 https://sites.google.com/a/chromium.org/chromedriver/downloads이 사이트를 들어가서 내 크롬 버전에 맞는 드라이버를 다운받아야한다. 다운 받아서 압축만 풀어두면 사전작업 끝. 대신 디렉터리를 알아둬야하는데 난 그냥 다운로드 디렉토리에 두어서 '/Users/sowon/Downloads/chromedriver' 이런식이다.

 

from selenium import webdriver
from bs4 import BeautifulSoup


def crawl_video_url(num) :
	#크롤링
    options = webdriver.ChromeOptions()
    options.add_argument('headless')
    driver = webdriver.Chrome('/Users/sowon/Downloads/chromedriver', options=options)
    driver.get('http://sldict.korean.go.kr/front/sign/signContentsView.do?origin_no={}'.format(num))
	
    #selenium으로 크롤링한 페이지 소스 중에 필요한 부분 찾는거는 beautifulSoup 그냥 씀 이게 편해서
    html = driver.page_source
    soup = BeautifulSoup(html,'html.parser')
    video_url = soup.find(type="video/mp4").get("src")
    print(video_url)
    save_video(video_url)

 

코드는 간단하다. driver 변수를 선언하는 코드에 아까 다운받은 드라이버 디렉터리만 붙여놓으면 된다. 사실 함수 시작하고 3줄만 있어도 크롤링이 되는데 options.add_argument('headless') 이거를 선언안하니까 코드를 수행하면 크롬 창이 자동으로 떠서 주소로 돌아간다. 마치 팀뷰어로 내 컴퓨터를 조종하는 느낌.

어쨌든 저 코드를 쓰고 driver작업에서 options을 지정해주면 실행해도 창이 안뜨고 작업이 수행된다.

 

 

-------------------------------------------------------------------------------------------------------

html 변수 부터 코드는 주소 찾아내는 코드라서 중요하진 않다.

 

문제는 그냥 bs4만 써도 1초는 걸렸는데, selenium을 쓰면 실행하고 5초는 지나야 값이 리턴된다. 빠른 동작을 필수로 하는 우리 프로젝트에는 너무 치명적이다. 드라이버 문제일까봐 팬텀js도 써봤는데 warning 안내만 추가되고 시간은 비슷하게 걸리더라. headless가 요즘 대세라고 해서 써보려했는데 내 크롬 버전에 맞는게 없다. 날라갈까봐 살짝 두려워서 보류해두었는데 시도해볼 예정임

 

마지막 코드인 save video 함수는 영상 주소를 활용해서 영상을 다운받는 함수로 다음 게시물에서 안내한다.

728x90
반응형
728x90
반응형

  1) anaconda prompt 실행(그냥 cmd에서 하면 안됨ㅜ)

  2) pip install tensorflow 명령어 입력하여 텐서플로우 설치

  3) 설치 완료되면 python 입력하여 파이썬 커맨드 라인으로 입장

  4) import tensorflow as tf 

     hello = tf.constant('hello world')

     tf.print(hello)

   실행하여 tensorflow가 잘 작동되는지 확인

 

728x90
반응형

'IT > AI' 카테고리의 다른 글

TensorFlow정리  (0) 2021.01.27
728x90
반응형

Java : 

https://stackoverrun.com/ko/q/10703531: stereo Mix라는 단서 발견 but 확실치 않음

https://stackoverrun.com/ko/q/1485826 -> https://namu.wiki/w/WASAPI : 레퍼런스에서 WASAPI라는것을 활용하면 가능할 수 있다했지만 이는 윈도우에서 제공하는 오디오 모듈로 이도 확실치 않ㅇ...

https://gist.github.com/lifove/7e14530a56fcd870632cb8a471eee570

https://stackoverrun.com/ko/q/2262359

https://stackoverrun.com/ko/q/4196572 : 여기서는 자바에선 불가능하고 윈도우 PortAudio API쓰면 될거같다고 추측중

안드로이드 : 볼륨 컨트롤은 되지만 소리받아오기는 불가한것으로 보임.

https://m.blog.naver.com/PostView.nhn?blogId=neocold&logNo=90102798676&proxyReferer=https:%2F%2Fwww.google.com%2F

 

C++ : 

https://stackoverrun.com/ko/q/3482742

https://www.python2.net/questions-865.htm: stereo mixㅡㄹ 활용한다는 가능성을 보여주지만 이또한 레퍼런스가 없음

https://technicalustad.com/enable-stereo-mix-in-windows-10/: 이건 stereo mix 에 대한 설명

https://stackoverrun.com/ko/q/10290034: 희망한줄기 보일듯말듯

https://patents.google.com/patent/KR100521366B1/ko: 참고자료

728x90
반응형

'IT > 고민' 카테고리의 다른 글

VS code 설정  (0) 2022.06.11
[for-sign] 형태소분석 오류잡기1  (0) 2021.01.27
Django vs Node JS  (0) 2021.01.27
728x90
반응형

1. 간단 필수 명령

git init : Github에 저장소 작성

git clone : Github에 저장소 복제

git add : 파일의 생성

git commit -m "filename" : 변경 결과를 로컬 저장소에 커밋

git remote add origin https://github.com/username/repositary 

git push origin master : 로컬 저장소를 밀어 원격 저장소에 반영

 

2. 브랜치 관리

git branch : 브랜치 목록

git branch asdf : asdf 라는 브랜치 생성

git checkout asdf : 지점의 이동

git checkout -b asdf : 지점만들기 및 이동

git merge asdf : 브랜치 결과 병합

git branch -d asdf : 브랜치 삭제

 

3. 자주사용하는 명령어

git status : 중요) 저장소의 상태 확인

git log : 로컬 저장소의 커밋 히스토리를 탐색

git greb "asdf" : 저장소의 파일 내용에서 검색

git clone : 기존 원격 저장소를 로컬에 다운로드

git remote : 원격 저장소를 조작하는 데에 사용하는 명령

git reset : 로컬 저장소의 커밋을 취소

git pull : 원격 브랜치의 변경 사항을 캡처

728x90
반응형

'IT > GIT' 카테고리의 다른 글

깃허브 커밋 메시지  (0) 2021.03.16
Git 공부  (0) 2021.01.27
728x90
반응형

1. AndroidManifest.xml 파일에 인터넷과 오디오 접근 허용을 위한 문장을 추가한다.

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

 

2. activity_main.xml 파일에 Textview 와 Button 을 하나씩 추가한다.

Textview : stt 결과를 출력하기 위함

Button : stt 명령을 시작하기 위함

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/sttResult"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="STT 결과"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.405" />

    <Button
        android:id="@+id/sttStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="154dp"
        android:layout_marginTop="62dp"
        android:text="STT Button"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/sttResult" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

3. MainActivity.java 파일에 STT 기능을 추가한다.

package com.example.testapp;

import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    Intent intent;
    SpeechRecognizer mRecognizer;
    Button sttBtn;
    TextView textView;
    final int PERMISSION = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if ( Build.VERSION.SDK_INT >= 23 ){
            // 퍼미션 체크
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.INTERNET,
                    Manifest.permission.RECORD_AUDIO},PERMISSION);
        }

        textView = findViewById(R.id.sttResult);
        sttBtn = findViewById(R.id.sttStart);

        intent=new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,getPackageName());
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,"ko-KR");
        sttBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mRecognizer=SpeechRecognizer.createSpeechRecognizer(MainActivity.this);
                mRecognizer.setRecognitionListener(listener);
                mRecognizer.startListening(intent);
            }
        });
    }

    private RecognitionListener listener = new RecognitionListener() {
        @Override
        public void onReadyForSpeech(Bundle params) {
            Toast.makeText(getApplicationContext(),"음성인식을 시작합니다.",Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onBeginningOfSpeech() {}

        @Override
        public void onRmsChanged(float rmsdB) {}

        @Override
        public void onBufferReceived(byte[] buffer) {}

        @Override
        public void onEndOfSpeech() {}

        @Override
        public void onError(int error) {
            String message;

            switch (error) {
                case SpeechRecognizer.ERROR_AUDIO:
                    message = "오디오 에러";
                    break;
                case SpeechRecognizer.ERROR_CLIENT:
                    message = "클라이언트 에러";
                    break;
                case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
                    message = "퍼미션 없음";
                    break;
                case SpeechRecognizer.ERROR_NETWORK:
                    message = "네트워크 에러";
                    break;
                case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
                    message = "네트웍 타임아웃";
                    break;
                case SpeechRecognizer.ERROR_NO_MATCH:
                    message = "찾을 수 없음";
                    break;
                case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
                    message = "RECOGNIZER가 바쁨";
                    break;
                case SpeechRecognizer.ERROR_SERVER:
                    message = "서버가 이상함";
                    break;
                case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
                    message = "말하는 시간초과";
                    break;
                default:
                    message = "알 수 없는 오류임";
                    break;
            }

            Toast.makeText(getApplicationContext(), "에러가 발생하였습니다. : " + message,Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onResults(Bundle results) {
            ArrayList<String> matches =
                    results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

            for(int i = 0; i < matches.size() ; i++){
                textView.setText(matches.get(i));
            }
        }

        @Override
        public void onPartialResults(Bundle partialResults) {}

        @Override
        public void onEvent(int eventType, Bundle params) {}
    };
}

 

4. 결과 

 

 

 

 

https://medium.com/wasd/creating-an-android-google-stt-application-4cea24ee97af

 

 

Creating an Android Google STT application

STT(Speech to Text)로 음성인식 어플을 만들기

medium.com

위 블로그를 참고하여 작성하였습니다.

728x90
반응형

'IT > API' 카테고리의 다른 글

API 호출 시 파라미터가 없는 버그  (0) 2022.09.27
STT API 실행파일로 만들기!!!  (0) 2021.01.27
STT 과제 - Google STT 활용  (0) 2021.01.27
728x90
반응형

 

import java.util.Arrays;
class Solution {
    public String solution(String[] participantString[] completion) {
        Arrays.sort(participant);
        Arrays.sort(completion);
        int i = 0;
        for(i = 0 ; i < completion.length; i++){
            if(!participant[i].equals(completion[i])) return participant[i];
        }
        return participant[i];
    }
}

사용한 함수

 

 

 

Array.sort() : 배열을 정렬해준다.

728x90
반응형

+ 최근 게시글