Python의 특정 회의 내에서 Google 학술 논문 긁기

  • What will be scraped
  • How to filtering works
  • Prerequisites
  • Full Code
  • Links
  • Outro

  • 스크랩 할 것





    필터링 작동 방식



    결과를 필터링하려면 이름에 source:가 포함된 소스에서 게시한 문서로 검색 결과를 제한하는 "NIPS" 연산자를 사용해야 합니다.

    이 연산자는 OR 연산자, 즉 source:NIPS OR source:"Neural Information" 외에도 사용할 수 있습니다. 따라서 검색어는 다음과 같습니다.

    search terms source:NIPS OR source:"Neural Information"
    


    전제 조건



    CSS 선택자를 사용한 기본 지식 스크래핑

    CSS 선택기는 스타일이 적용되는 마크업 부분을 선언하므로 일치하는 태그 및 속성에서 데이터를 추출할 수 있습니다.

    CSS 선택기로 스크랩하지 않은 경우 그것이 무엇인지, 장단점, 웹 스크래핑 관점에서 왜 중요한지, 그리고 가장 일반적인 접근 방식을 보여주는 전용 블로그 게시물how to use CSS selectors when web-scraping이 있습니다. 웹 스크래핑 시 CSS 선택기를 사용합니다.

    프로젝트일 경우 별도의 가상 환경

    요컨대, 동일한 시스템에서 서로 공존할 수 있는 서로 다른 Python 버전을 포함하여 설치된 라이브러리의 독립 세트를 생성하여 라이브러리 또는 Python 버전 충돌을 방지하는 것입니다.

    이전에 가상 환경으로 작업한 적이 없다면 내 전용 블로그 게시물Python virtual environments tutorial using Virtualenv and Poetry을 살펴보고 익숙해지십시오.

    📌참고: 이것은 이 블로그 게시물에 대한 엄격한 요구 사항이 아닙니다.

    라이브러리 설치:

    pip install requests parsel
    


    차단될 확률 감소

    요청이 차단될 가능성이 있습니다. how to reduce the chance of being blocked while web-scraping을 살펴보십시오. 대부분의 웹사이트에서 차단을 우회하는 11가지 방법이 있습니다.


    전체 코드




    from parsel import Selector
    import requests, json, os
    
    
    def check_sources(source: list or str):
        if isinstance(source, str):
            return source                                             # NIPS
        elif isinstance(source, list):
            return " OR ".join([f'source:{item}' for item in source]) # source:NIPS OR source:Neural Information
    
    
    def scrape_conference_publications(query: str, source: list or str):
        # https://docs.python-requests.org/en/master/user/quickstart/#passing-parameters-in-urls
        params = {
            "q": f'{query.lower()} {check_sources(source=source)}',  # search query
            "hl": "en",                         # language of the search
            "gl": "us"                          # country of the search
        }
    
        # https://docs.python-requests.org/en/master/user/quickstart/#custom-headers
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
        }
    
        html = requests.get("https://scholar.google.com/scholar", params=params, headers=headers, timeout=30)
        selector = Selector(html.text)
    
        publications = []
    
        for result in selector.css(".gs_r.gs_scl"):
            title = result.css(".gs_rt").xpath("normalize-space()").get()
            link = result.css(".gs_rt a::attr(href)").get()
            result_id = result.attrib["data-cid"]
            snippet = result.css(".gs_rs::text").get()
            publication_info = result.css(".gs_a").xpath("normalize-space()").get()
            cite_by_link = f'https://scholar.google.com/scholar{result.css(".gs_or_btn.gs_nph+ a::attr(href)").get()}'
            all_versions_link = f'https://scholar.google.com/scholar{result.css("a~ a+ .gs_nph::attr(href)").get()}'
            related_articles_link = f'https://scholar.google.com/scholar{result.css("a:nth-child(4)::attr(href)").get()}'
            pdf_file_title = result.css(".gs_or_ggsm a").xpath("normalize-space()").get()
            pdf_file_link = result.css(".gs_or_ggsm a::attr(href)").get()
    
            publications.append({
                "result_id": result_id,
                "title": title,
                "link": link,
                "snippet": snippet,
                "publication_info": publication_info,
                "cite_by_link": cite_by_link,
                "all_versions_link": all_versions_link,
                "related_articles_link": related_articles_link,
                "pdf": {
                    "title": pdf_file_title,
                    "link": pdf_file_link
                }
            })
    
        # return publications
    
        print(json.dumps(publications, indent=2, ensure_ascii=False))
    
    
    scrape_conference_publications(query="anatomy", source=["NIPS", "Neural Information"])
    


    코드 설명


    list 또는 strstr를 받아들이고 list인 경우 변환하는 함수를 추가합니다.

    def check_sources(source: list or str):
        if isinstance(source, str):
            return source                                             # NIPS
        elif isinstance(source, list):
            return " OR ".join([f'source:{item}' for item in source]) # source:NIPS OR source:Neural Information
    


    구문 분석 함수를 정의합니다.

    def scrape_conference_publications(query: str, source: list or str):
        # further code...
    



    암호
    설명

    query: strPython에게 query 인수가 string 여야 한다고 알려줍니다.
    source: list or str파이썬에게 source 인수가 list 또는 string 여야 한다고 알려줍니다.


    URL 매개변수user-agent를 생성하고 요청에 전달합니다.

    # https://docs.python-requests.org/en/master/user/quickstart/#passing-parameters-in-urls
    params = {
        "q": f'{query.lower()} {sources}',  # search query
        "hl": "en",                         # language of the search
        "gl": "us"                          # country of the search
    }
    
    # https://docs.python-requests.org/en/master/user/quickstart/#custom-headers
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
    }
    
    html = requests.get("https://scholar.google.com/scholar", params=params, headers=headers, timeout=30)
    selector = Selector(html.text)
    



    암호
    설명


    timeout
    30초 후에 응답 대기를 중지하도록 요청에 알립니다.
    Selector데이터를 구문 분석하는 HTML/XML 프로세서입니다. 좋아요 BeautifulSoup() .

    user-agent
    "실제"사용자 방문으로 작동하는 데 사용됩니다. Default requests user-agent is a python-requests 따라서 웹사이트는 요청을 보내고 차단할 수 있는 스크립트임을 이해합니다. Check what's your user-agent .


    임시 파일list을 만들어 데이터를 저장하고 유기적 결과를 반복합니다.

    publications = []
    
    for result in selector.css(".gs_r.gs_scl"):
        title = result.css(".gs_rt").xpath("normalize-space()").get()
        link = result.css(".gs_rt a::attr(href)").get()
        result_id = result.attrib["data-cid"]
        snippet = result.css(".gs_rs::text").get()
        publication_info = result.css(".gs_a").xpath("normalize-space()").get()
        cite_by_link = f'https://scholar.google.com/scholar{result.css(".gs_or_btn.gs_nph+ a::attr(href)").get()}'
        all_versions_link = f'https://scholar.google.com/scholar{result.css("a~ a+ .gs_nph::attr(href)").get()}'
        related_articles_link = f'https://scholar.google.com/scholar{result.css("a:nth-child(4)::attr(href)").get()}'
        pdf_file_title = result.css(".gs_or_ggsm a").xpath("normalize-space()").get()
        pdf_file_link = result.css(".gs_or_ggsm a::attr(href)").get()
    



    암호
    설명

    css(<selector>)
    to extarct data from a given CSS selector . 백그라운드에서 parselcssselect를 사용하여 모든 CSS 쿼리를 XPath 쿼리로 변환합니다.
    xpath("normalize-space()")
    to get blank text nodes as well . 기본적으로 빈 텍스트 노드는 건너뛰어 완전한 출력이 되지 않습니다.
    ::text/::attr()
    HTML 노드의 parsel pseudo-elements to extract text or attribute 데이터입니다.
    get()실제 데이터를 얻기 위해


    결과를 임시 목록에 사전으로 추가하고 추출된 데이터를 반환하거나 인쇄합니다.

    publications.append({
            "result_id": result_id,
            "title": title,
            "link": link,
            "snippet": snippet,
            "publication_info": publication_info,
            "cite_by_link": cite_by_link,
            "all_versions_link": all_versions_link,
            "related_articles_link": related_articles_link,
            "pdf": {
                "title": pdf_file_title,
                "link": pdf_file_link
            }
        })
    
    # return publications
    
    print(json.dumps(publications, indent=2, ensure_ascii=False))
    
    
    scrape_conference_publications(query="anatomy", source=["NIPS", "Neural Information"])
    


    출력:

    [
      {
        "result_id": "hjgaRkq_oOEJ",
        "title": "Differential representation of arm movement direction in relation to cortical anatomy and function",
        "link": "https://iopscience.iop.org/article/10.1088/1741-2560/6/1/016006/meta",
        "snippet": "… ",
        "publication_info": "T Ball, A Schulze-Bonhage, A Aertsen… - Journal of neural …, 2009 - iopscience.iop.org",
        "cite_by_link": "https://scholar.google.com/scholar/scholar?cites=16258204980532099206&as_sdt=2005&sciodt=0,5&hl=en",
        "all_versions_link": "https://scholar.google.com/scholar/scholar?cluster=16258204980532099206&hl=en&as_sdt=0,5",
        "related_articles_link": "https://scholar.google.com/scholar/scholar?q=related:hjgaRkq_oOEJ:scholar.google.com/&scioq=anatomy+source:NIPS+OR+source:Neural+Information&hl=en&as_sdt=0,5",
        "pdf": {
          "title": "[PDF] psu.edu",
          "link": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.324.1523&rep=rep1&type=pdf"
        }
      }, ... other results
    ]
    



    또는 SerpApi에서 Google Scholar Organic Results API을 사용하여 이를 달성할 수 있습니다.

    가장 큰 차이점은 파서를 처음부터 만들고 유지 관리하고 확장 방법을 알아낼 필요가 없으며 가장 중요한 것은 Google에서 블록을 우회하여 프록시 및 CAPTCHA 해결 솔루션을 설정하는 방법을 알아내는 방법입니다.

    # pip install google-search-results
    
    import os, json
    from serpapi import GoogleSearch
    from urllib.parse import urlsplit, parse_qsl
    
    params = {
        # https://docs.python.org/3/library/os.html#os.getenv
        "api_key": os.getenv("API_KEY"), # your serpapi API key
        "engine": "google_scholar",      # search engine
        "q": "AI source:NIPS",           # search query
        "hl": "en",                      # language
        # "as_ylo": "2017",              # from 2017
        # "as_yhi": "2021",              # to 2021
        "start": "0"                     # first page
        }
    
    search = GoogleSearch(params)
    
    publications = []
    
    publications_is_present = True
    while publications_is_present:
        results = search.get_dict()
    
        print(f"Currently extracting page #{results.get('serpapi_pagination', {}).get('current')}..")
    
        for result in results["organic_results"]:
            position = result["position"]
            title = result["title"]
            publication_info_summary = result["publication_info"]["summary"]
            result_id = result["result_id"]
            link = result.get("link")
            result_type = result.get("type")
            snippet = result.get("snippet")
    
            publications.append({
                "page_number": results.get("serpapi_pagination", {}).get("current"),
                "position": position + 1,
                "result_type": result_type,
                "title": title,
                "link": link,
                "result_id": result_id,
                "publication_info_summary": publication_info_summary,
                "snippet": snippet,
                })
    
    
            if "next" in results.get("serpapi_pagination", {}):
                # splits URL in parts as a dict and passes it to a GoogleSearch() class.
                search.params_dict.update(dict(parse_qsl(urlsplit(results["serpapi_pagination"]["next"]).query)))
            else:
                papers_is_present = False
    
    print(json.dumps(organic_results_data, indent=2, ensure_ascii=False))
    


    연결


  • Code in the onlie IDE
  • SerpApi Google Scholar Organic Results API



  • 가입 |

    Feature Request 💫 또는 Bug 🐞 추가

    좋은 웹페이지 즐겨찾기