Python에서 ResearchGate 검색의 모든 질문을 웹 스크래핑
                                            
                                                
                                                
                                                
                                                
                                                
                                                 32765 단어  tutorialprogrammingwebscrapingpython
                    
소개
현재 ResearchGate 검색 - 질문 페이지에서 데이터 추출을 지원하는 API가 없습니다.
이 블로그 게시물은 적절한 API를 출시하는 동안 아래에 제공된 DIY 솔루션을 사용하여 직접 할 수 있는 방법을 보여주기 위한 것입니다.
이 솔루션은 당사Legal US Shield에 대해 제공하는 paid production and above plans을 포함하지 않고, 예를 들어 CAPTCHA와 같은 블록을 우회해야 하는 등의 제한 사항이 있으므로 개인 용도로 사용할 수 있습니다.
공개 로드맵을 확인하여 이 API에 대한 프로세스를 추적할 수 있습니다.
🗺 [New API] ResearchGate Search: Publications, Authors, Questions
스크랩 할 것

전제 조건
CSS 선택자를 사용한 기본 지식 스크래핑
CSS 선택기로 스크랩하지 않은 경우 그것이 무엇인지, 장단점, 웹 스크래핑 관점에서 왜 중요한지, 그리고 가장 일반적인 접근 방식을 보여주는 전용 블로그 게시물how to use CSS selectors when web-scraping이 있습니다. 웹 스크래핑 시 CSS 선택기를 사용합니다.
별도의 가상 환경
이전에 가상 환경으로 작업한 적이 없다면 내 전용 블로그 게시물Python virtual environments tutorial using Virtualenv and Poetry을 살펴보고 익숙해지십시오.
차단될 확률 감소
요청이 차단될 가능성이 있습니다. how to reduce the chance of being blocked while web-scraping을 살펴보십시오. 대부분의 웹사이트에서 차단을 우회하는 11가지 방법이 있습니다.
📌참고: 이것은 이 블로그 게시물에 대한 엄격한 요구 사항이 아닙니다.
라이브러리 설치:
pip install parsel playwright
전체 코드
from parsel import Selector
from playwright.sync_api import sync_playwright
import json
def scrape_researchgate_questions(query: str):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True, slow_mo=50)
        page = browser.new_page(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36")
        questions = []
        page_num = 1
        while True:
            page.goto(f"https://www.researchgate.net/search/question?q={query}&page={page_num}")
            selector = Selector(text=page.content())
            for question in selector.css(".nova-legacy-c-card__body--spacing-inherit"):
                title = question.css(".nova-legacy-v-question-item__title .nova-legacy-e-link--theme-bare::text").get().title()
                title_link = f'https://www.researchgate.net{question.css(".nova-legacy-v-question-item__title .nova-legacy-e-link--theme-bare::attr(href)").get()}'
                question_type = question.css(".nova-legacy-v-question-item__badge::text").get()
                question_date = question.css(".nova-legacy-v-question-item__meta-data-item:nth-child(1) span::text").get()
                snippet = question.css(".redraft-text::text").get()
                views = question.css(".nova-legacy-v-question-item__metrics-item:nth-child(1) .nova-legacy-e-link--theme-bare::text").get()
                views_link = question.css(".nova-legacy-v-question-item__metrics-item:nth-child(1) .nova-legacy-e-link--theme-bare::attr(href)").get()
                answer = question.css(".nova-legacy-v-question-item__metrics-item+ .nova-legacy-v-question-item__metrics-item .nova-legacy-e-link--theme-bare::text").get()
                answer_link = question.css(".nova-legacy-v-question-item__metrics-item+ .nova-legacy-v-question-item__metrics-item .nova-legacy-e-link--theme-bare::attr(href)").get()
                questions.append({
                    "title": title,
                    "link": title_link,
                    "snippet": snippet,
                    "question_type": question_type,
                    "question_date": question_date,
                    "views": {
                        "views_count": views,
                        "views_link": views_link
                        },
                    "answer": {
                        "answer_count": answer,
                        "answers_link": answer_link
                    }
                })
            print(f"page number: {page_num}")
            # checks if next page arrow key is greyed out `attr(rel)` (inactive) and breaks out of the loop
            if selector.css(".nova-legacy-c-button-group__item:nth-child(9) a::attr(rel)").get():
                break
            else:
                page_num += 1
        print(json.dumps(questions, indent=2, ensure_ascii=False))
        browser.close()
scrape_researchgate_questions(query="coffee")
코드 설명
라이브러리 가져오기:
from parsel import Selector
from playwright.sync_api import sync_playwright
import json
암호
설명
parsel HTML/XML 문서를 구문 분석합니다. XPath를 지원합니다.
playwright 브라우저 인스턴스로 페이지를 렌더링합니다.
jsonPython 사전을 JSON 문자열로 변환합니다.함수를 정의하고 context manager::으로
playwright를 엽니다.scrape_researchgate_questions(query="coffee"):
    with sync_playwright() as p:
        # ...
암호
설명
query: str파이썬에게 query 가 str 가 되어야 한다고 알려줍니다.브라우저 인스턴스를 실행하고
new_page를 통과하여 엽니다user-agent.browser = p.chromium.launch(headless=True, slow_mo=50)
page = browser.new_page(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36")
암호
설명
p.chromium.launch() Chromium 브라우저 인스턴스를 시작합니다.
headless 기본 값이더라도 헤드리스 모드에서 실행하도록 명시적으로 지시합니다
playwright.slow_mo 실행 속도를 늦추라고 지시합니다
playwright.browser.new_page() 새 페이지를 엽니다.
user_agent는 실제 사용자가 브라우저에서 요청을 수행하는 데 사용됩니다. 사용하지 않으면 기본적으로 playwright 값인 None 가 됩니다. Check what's your user-agent .임시 목록을 추가하고, while 루프를 설정하고, 새 URL을 엽니다.
questions = []
while True:
    page.goto(f"https://www.researchgate.net/search/question?q={query}&page={page_num}")
    selector = Selector(text=page.content())
    # ...
암호
설명
goto()전달된 쿼리 및 페이지 매개변수를 사용하여 특정 URL을 요청합니다.Selector()반환된 HTML 데이터를 page.content()로 전달하고 처리합니다.각 페이지에서 작성자 결과를 반복하고 데이터를 추출하고
append 임시list로:for question in selector.css(".nova-legacy-c-card__body--spacing-inherit"):
    title = question.css(".nova-legacy-v-question-item__title .nova-legacy-e-link--theme-bare::text").get().title()
    title_link = f'https://www.researchgate.net{question.css(".nova-legacy-v-question-item__title .nova-legacy-e-link--theme-bare::attr(href)").get()}'
    question_type = question.css(".nova-legacy-v-question-item__badge::text").get()
    question_date = question.css(".nova-legacy-v-question-item__meta-data-item:nth-child(1) span::text").get()
    snippet = question.css(".redraft-text::text").get()
    views = question.css(".nova-legacy-v-question-item__metrics-item:nth-child(1) .nova-legacy-e-link--theme-bare::text").get()
    views_link = question.css(".nova-legacy-v-question-item__metrics-item:nth-child(1) .nova-legacy-e-link--theme-bare::attr(href)").get()
    answer = question.css(".nova-legacy-v-question-item__metrics-item+ .nova-legacy-v-question-item__metrics-item .nova-legacy-e-link--theme-bare::text").get()
    answer_link = question.css(".nova-legacy-v-question-item__metrics-item+ .nova-legacy-v-question-item__metrics-item .nova-legacy-e-link--theme-bare::attr(href)").get()
    questions.append({
        "title": title,
        "link": title_link,
        "snippet": snippet,
        "question_type": question_type,
        "question_date": question_date,
        "views": {
            "views_count": views,
            "views_link": views_link
            },
        "answer": {
            "answer_count": answer,
            "answers_link": answer_link
        }
    })
암호
설명
css()to parse data from the passed CSS selector(s) . 후드 아래의 모든 CSS query traslates to XPath using
csselect  package.::text/::attr(attribute)to extract textual or attribute data 노드에서.
get()/getall()to get actual data from a matched node , 또는 get a
list  of matched data from nodes .xpath("normalize-space()")빈 텍스트 노드도 구문 분석합니다. 기본적으로 빈 텍스트 노드는 XPath에서 건너뜁니다.다음 페이지가 있는지 확인하고 페이지를 매깁니다.
# checks if the next page arrow key is greyed out `attr(rel)` (inactive) -> breaks out of the loop
if selector.css(".nova-legacy-c-button-group__item:nth-child(9) a::attr(rel)").get():
    break
else:
    page_num += 1
추출된 데이터 및
close 브라우저 인스턴스 인쇄:print(json.dumps(publications, indent=2, ensure_ascii=False))
browser.close()
# call the function
scrape_researchgate_questions(query="coffee")
JSON 출력의 일부:
[
  {
    "title": "Any Recommendations On An Inexpensive Coffee Grinder To Grind Up Bark Samples To Measure Ph?",
    "link": "https://www.researchgate.netpost/Any_recommendations_on_an_inexpensive_coffee_grinder_to_grind_up_bark_samples_to_measure_pH?_sg=tsmZvLsXrFpn6TG77ljxS8pVJhdOMYVlqqYhQl0BszqPCDW1__lnpczwZl8XJiVROJ8_8G8jaerzpX8",
    "snippet": "We are folloiwng protocol by Hansen et al. (2015) Sci. Pharm. They recommend a Rancilio coffee grinder but these are several hundred dollars. Hoping to use something a little less expensive.",
    "question_type": "Question",
    "question_date": "Oct 2017",
    "views": {
      "views_count": "97 Views",
      "views_link": "post/Any_recommendations_on_an_inexpensive_coffee_grinder_to_grind_up_bark_samples_to_measure_pH?_sg=tsmZvLsXrFpn6TG77ljxS8pVJhdOMYVlqqYhQl0BszqPCDW1__lnpczwZl8XJiVROJ8_8G8jaerzpX8"
    },
    "answer": {
      "answer_count": "2 Answers",
      "answers_link": "https://www.researchgate.netpost/Any_recommendations_on_an_inexpensive_coffee_grinder_to_grind_up_bark_samples_to_measure_pH?_sg=tsmZvLsXrFpn6TG77ljxS8pVJhdOMYVlqqYhQl0BszqPCDW1__lnpczwZl8XJiVROJ8_8G8jaerzpX8"
    }
  }, ... other questions
  {
    "title": "Are There Any Ways To Find The Concentration Of A Solution Where Its Chemical Formula And Number Of Moles Are Unknown? ",
    "link": "https://www.researchgate.netpost/Are_there_any_ways_to_find_the_concentration_of_a_solution_where_its_chemical_formula_and_number_of_moles_are_unknown?_sg=6W-hvIYx-FRel_YiWd62lbksTzeWP7GVkZ3tVO6SgZI7F_czhLz_oFCduq9DVhrhvIUy97168wXrn30",
    "snippet": "A comprehensive way to find the concentration of random solutions would enhance benefits related with health, industry, technology and commercial aspects. Although beer lambert law is a solution, there are some cases where Epsilon is unknown (Example: A Coca-Cola drink or a cup of coffee). In this cases, proper alt",
    "question_type": "Question",
    "question_date": "Jan 2022",
    "views": {
      "views_count": "742 Views",
      "views_link": "post/Are_there_any_ways_to_find_the_concentration_of_a_solution_where_its_chemical_formula_and_number_of_moles_are_unknown?_sg=6W-hvIYx-FRel_YiWd62lbksTzeWP7GVkZ3tVO6SgZI7F_czhLz_oFCduq9DVhrhvIUy97168wXrn30"
    },
    "answer": {
      "answer_count": "4 Answers",
      "answers_link": "https://www.researchgate.netpost/Are_there_any_ways_to_find_the_concentration_of_a_solution_where_its_chemical_formula_and_number_of_moles_are_unknown?_sg=6W-hvIYx-FRel_YiWd62lbksTzeWP7GVkZ3tVO6SgZI7F_czhLz_oFCduq9DVhrhvIUy97168wXrn30"
    }
  }
]
연결
가입 |
Feature Request 💫 또는 Bug 🐞 추가
Reference
이 문제에 관하여(Python에서 ResearchGate 검색의 모든 질문을 웹 스크래핑), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dmitryzub/web-scraping-all-questions-from-researchgate-search-in-python-2ipk텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)