Как стать автором
Обновить

Парсинг исторических данных с Google Scholar используя Python

Время на прочтение16 мин
Количество просмотров6.5K

👉Кратко о сути: парсинг исторических органических и цитируемых результатов 2017-2021 годов с Google Scholar используя пагинацию. Следом их сохранение в CSV и SQLite БД используя Python и библиотеку для веб-скрейпинга от SerpApi.

🔨Что понадобится: понимание циклов, структур данных, обработка исключений. А так же serpapi, urllib, pandas, sqlite3 библиотеки.

⏱️Сколько времени займет: ~20-60 минут на чтение и реализацию.


Что парсим

Из органических результатов:

📌Примечание: На Google Scholar есть максимальный лимит в 100 страниц, поэтому когда вы видите About xxx.xxx results это не означает что все результаты отображаются и их можно спарсить. Так же как это происходит с Гугл поиском.

Из цитируемых результатов:

Что понадобится

Отдельное вирутуальное окружение

Если вы не работали с виртуальным окружением ранее, взгляните на посвященный этому блог пост на английском языке - Python virtual environments tutorial using Virtualenv and Poetry.

Вкратце, это штука, которая создает независимый набор установленных библиотек включая возможность установки разных версий Python которые могут сосуществовать друг с другом одновременно на одной системе, что в свою очередь предотвращает конфликты библиотек и разных версий Python.

📌Примечание: использование виртуальной среды не является строгим требованием.

Установка библиотек:

pip install google-search-results
pip install pandas

Процесс

Если объяснение не нужно:

Органические результаты

import os
from serpapi import GoogleSearch
from urllib.parse import urlsplit, parse_qsl


def organic_results():
    print("extracting organic results..")

    params = {
        "api_key": os.getenv("API_KEY"), # ключ для аутентификации в SerpApi 
        "engine": "google_scholar",
        "q": "minecraft redstone system structure characteristics strength",  # поисковый запрос
        "hl": "en",        # язык
        "as_ylo": "2017",  # с 2017
        "as_yhi": "2021",  # до 2021
        "start": "0"       # первая страница
    }

    search = GoogleSearch(params)

    organic_results_data = []

    loop_is_true = True

    while loop_is_true:
        results = search.get_dict()

        print(f"Currently extracting page №{results['serpapi_pagination']['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")
  
            try:
              file_title = result["resources"][0]["title"]
            except: file_title = None
  
            try:
              file_link = result["resources"][0]["link"]
            except: file_link = None
  
            try:
              file_format = result["resources"][0]["file_format"]
            except: file_format = None
  
            try:
              cited_by_count = int(result["inline_links"]["cited_by"]["total"])
            except: cited_by_count = None
  
            cited_by_id = result.get("inline_links", {}).get("cited_by", {}).get("cites_id", {})
            cited_by_link = result.get("inline_links", {}).get("cited_by", {}).get("link", {})
  
            try:
              total_versions = int(result["inline_links"]["versions"]["total"])
            except: total_versions = None
  
            all_versions_link = result.get("inline_links", {}).get("versions", {}).get("link", {})
            all_versions_id = result.get("inline_links", {}).get("versions", {}).get("cluster_id", {})
  
            organic_results_data.append({
              "page_number": results["serpapi_pagination"]["current"],
              "position": position + 1,
              "result_type": result_type,
              "title": title,
              "link": link,
              "result_id": result_id,
              "publication_info_summary": publication_info_summary,
              "snippet": snippet,
              "cited_by_count": cited_by_count,
              "cited_by_link": cited_by_link,
              "cited_by_id": cited_by_id,
              "total_versions": total_versions,
              "all_versions_link": all_versions_link,
              "all_versions_id": all_versions_id,
              "file_format": file_format,
              "file_title": file_title,
              "file_link": file_link,
            })

            if "next" in results["serpapi_pagination"]:
                search.params_dict.update(dict(parse_qsl(urlsplit(results["serpapi_pagination"]["next"]).query)))
            else:
                loop_is_true = False

    return organic_results_data

Объяснение парсинга органических результатов используя пагинацию

Импортируем os, serpapi, urllib библиотеки:

import os
from serpapi import GoogleSearch
from urllib.parse import urlsplit, parse_qsl

Создаем и передаем поисковые параметры в GoogleSearch() где происходит все извлечение данных на бэкенде SerpApi:

params = {
  "api_key": os.getenv("API_KEY"), # ключ для аутентификации в SerpApi
  "engine": "google_scholar",
  "q": "minecraft redstone system structure characteristics strength",  # поисковый запрос
  "hl": "en",        # язык
  "as_ylo": "2017",  # с 2017
  "as_yhi": "2021",  # до 2021
  "start": "0"       # первая страница
}

search = GoogleSearch(params) # извлечение данных происходит тут

Создаём временный список list() для того чтобы сохранить данные которые будут дальше использоваться для сохранения в CSV или переданыcite_results() функции:

organic_results_data = []

Создаём while цикл для парсинга данных со всех доступных страниц:

loop_is_true = True

while loop_is_true:
    results = search.get_dict()
    
    # парсинг данных происходит тутачки..
    
    if "next" in results["serpapi_pagination"]:
        search.params_dict.update(dict(parse_qsl(urlsplit(results["serpapi_pagination"]["next"]).query)))
    else:
        loop_is_true = False
  • Если нет ссылки на следующую "next" страницу - while прекратится установив loop_is_true на False.

  • Если есть ссылка на следующую "next" страницу, search.params_dict.update разберет ссылку на части и передаст её к GoogleSearch(params) для результатов с новой страницы.

Парсим данные в for цикле:

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")
  
    try:
      file_title = result["resources"][0]["title"]
    except: file_title = None
  
    try:
      file_link = result["resources"][0]["link"]
    except: file_link = None
  
    try:
      file_format = result["resources"][0]["file_format"]
    except: file_format = None
  
    try:
      cited_by_count = int(result["inline_links"]["cited_by"]["total"])
    except: cited_by_count = None
  
    cited_by_id = result.get("inline_links", {}).get("cited_by", {}).get("cites_id", {})
    cited_by_link = result.get("inline_links", {}).get("cited_by", {}).get("link", {})
  
    try:
      total_versions = int(result["inline_links"]["versions"]["total"])
    except: total_versions = None
  
    all_versions_link = result.get("inline_links", {}).get("versions", {}).get("link", {})
    all_versions_id = result.get("inline_links", {}).get("versions", {}).get("cluster_id", {})
  • try/except блоки были использованы для обработки None значений когда они отсутствуют из Google бэкенда.

Если объединить все в один try блок, извлеченные данные могут быть неаккуратны, иными словами если ссылка или описание на самом деле есть в выдаче, вместо этого оно вернёт None, поэтому здесь много try/except блоков.

Добавляем извлеченные данные во временный list() список:

organic_results_data = []

# тут парсинг и while цикл... 

organic_results_data.append({
    "page_number": results["serpapi_pagination"]["current"],
    "position": position + 1,
    "result_type": result_type,
    "title": title,
    "link": link,
    "result_id": result_id,
    "publication_info_summary": publication_info_summary,
    "snippet": snippet,
    "cited_by_count": cited_by_count,
    "cited_by_link": cited_by_link,
    "cited_by_id": cited_by_id,
    "total_versions": total_versions,
    "all_versions_link": all_versions_link,
    "all_versions_id": all_versions_id,
    "file_format": file_format,
    "file_title": file_title,
    "file_link": file_link,
})

Возвращаем временный list() список с данными которые будут использоваться позже при парсинге Цитируемых результатов:

return organic_results_data

Цитируемые результаты

В этой секции мы используем возвращенные данные из органической выдачи и передадим result_id в поисковый запрос для того чтобы спарсить цитируемые результаты.

Если у вас уже есть result_ids, вы можете пропустить парсинг Органических результатов:

# если у вас есть список result_ids

result_ids = ["FDc6HiktlqEJ"..."FDc6Hikt21J"]
for citation in result_ids:
    params = {
        "api_key": "API_KEY",             # ключ для аутентификации в SerpApi
        "engine": "google_scholar_cite",  # движок для парсинга цитируемых результатов
        "q": citation                     # FDc6HiktlqEJ ... FDc6Hikt21J
    }
    search = GoogleSearch(params)
    results = search.get_dict()
    # дальнейший код парсинга..

Ниже примера кода парсинга цитируемых результатов вы так же найдете пошаговое объяснение того что в нём происходит.

import os
from serpapi import GoogleSearch
from google_scholar_organic_results import organic_results

def cite_results():

    print("extracting cite results..")

    citation_results = []

    for citation in organic_results():
        params = {
            "api_key": os.getenv("API_KEY"), # ключ для аутентификации в SerpApi
            "engine": "google_scholar_cite", # # движок для парсинга цитируемых результатов
            "q": citation["result_id"]       # # FDc6HiktlqEJ ... FDc6Hikt21J
        }

        search = GoogleSearch(params)
        results = search.get_dict()

        print(f"Currently extracting {citation['result_id']} citation ID.")

        for result in results["citations"]:
            cite_title = result["title"]
            cite_snippet = result["snippet"]

            citation_results.append({
                "organic_result_title": citation["title"],
                "organic_result_link": citation["link"],
                "citation_title": cite_title,
                "citation_snippet": cite_snippet
            })

    return citation_results

Объяснение парсинга цитируемых результатов

Создаём временный список list() для хранения извлеченных данных:

citation_results = []

Создаём for цикл для итерации по organic_results() результатам и передаем result_id в "q" поисковый запрос:

for citation in organic_results():
    params = {
      "api_key": os.getenv("API_KEY"), # ключ для аутентификации в SerpApi
      "engine": "google_scholar_cite", # # движок для парсинга цитируемых результатов
      "q": citation["result_id"]       # # FDc6HiktlqEJ ... FDc6Hikt21J
    }

    search = GoogleSearch(params)      # парсинг на бэкенде SerpApi
    results = search.get_dict()        # JSON конвертируется в словарь

Создаём второй for цикл и достукиваемся к данный таким же способом как и до словаря:

for result in results["citations"]:
    cite_title = result["title"]
    cite_snippet = result["snippet"]

Добавляем извелченные данные во временный список list() как словарь:

citation_results.append({
    "organic_result_title": citation["title"], # чтобы понимать откуда берутся Цитируемые результаты
    "organic_result_link": citation["link"],   # чтобы понимать откуда берутся Цитируемые результаты
    "citation_title": cite_title,
    "citation_snippet": cite_snippet
})

Возвращаем временный список list():

return citation_results

Сохраняем в CSV

Нам только нужно передать возвращенные данные из органических и цитируемых результатов в DataFrame data аргумент и сохранить to_csv().

import pandas as pd
from google_scholar_organic_results import organic_results
from google_scholar_cite_results import cite_results

print("waiting for organic results to save..")
pd.DataFrame(data=organic_results())
  .to_csv("google_scholar_organic_results.csv", encoding="utf-8", index=False)

print("waiting for cite results to save..")
pd.DataFrame(data=cite_results())
  .to_csv("google_scholar_citation_results.csv", encoding="utf-8", index=False)

Объяснение процесса сохранения в CSV

Импортируем organic_results() и cite_results() откуда возвращаются данные, и библиотеку pandas:

import pandas as pd
from google_scholar_organic_results import organic_results
from google_scholar_cite_results import cite_results

Сохраняем органические результаты to_csv():

pd.DataFrame(data=organic_results()) \
    .to_csv("google_scholar_organic_results.csv", encoding="utf-8", index=False)

Сохраняем цитируемые результаты to_csv():

pd.DataFrame(data=cite_results()) \
    .to_csv("google_scholar_citation_results.csv", encoding="utf-8", index=False)
  • data аргумент внутри DataFrame это извлеченные данные.

  • encoding='utf-8' аргумент просто для того чтобы все было корректно сохранено. Я использовал этот аргумент явно, несмотря на то что это его дефолтное значение.

  • index=False аргумент чтобы убрать дефолтные номера строк pandas.


Сохраняем в SQLite

После этой секции вы узнаете о том как:

  • сохранять данные в SQLite используя pandas,

  • функционирует SQLite,

  • подключаться и разрывать соединение с SQLite,

  • создавать и удалять таблицы/колонки,

  • добавлять данные в for цикле.

Пример того как функционирует SQLite:

1. открывается соединение
    2. транзакция начинается
        3. выполняется инструкция
    4. транзакция завершается
5. закрывается соединение

Сохранение данные в SQLite используя pandas

# https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_sql.html
import sqlite3
import pandas as pd
from google_scholar_organic_results import organic_results
from google_scholar_cite_results import cite_results

conn = sqlite3.connect("google_scholar_results.db")

# создавать таблицу ручными SQL запросами не нужно,
# pandas это сделает автоматически.

# сохраняет органические результаты в SQLite
pd.DataFrame(organic_results()).to_sql(name="google_scholar_organic_results", 
                                       con=conn, 
                                       if_exists="append", 
                                       index=False)

# сохраняет цитируемые результаты в SQLite
pd.DataFrame(cite_results()).to_sql(name="google_scholar_cite_results", 
                                    con=conn, 
                                    if_exists="append", 
                                    index=False)

conn.commit()
conn.close()
  • name это название SQL таблицы.

  • con это соединение с базой данных.

  • if_exists скажет pandas как себя вести если таблица уже существует. По умолчанию оно не сработает "fail" и вызовет raise ошибку ValueError. В данном случае pandas будет добавлять данные.

  • index=False чтобы убрать индекс столбцов от DataFrame.


Другой способ сохранения данных вручную используя запросы SQLite

import sqlite3

conn = sqlite3.connect("google_scholar_results.db")

conn.execute("""CREATE TABLE google_scholar_organic_results (
                page_number integer,
                position integer,
                result_type text,
                title text, 
                link text,
                snippet text,
                result_id text,
                publication_info_summary text,
                cited_by_count integer,
                cited_by_link text,
                cited_by_id text,
                total_versions integer,
                all_versions_link text,
                all_versions_id text,
                file_format text,
                file_title text,
                file_link text)""")
conn.commit()
            
 conn.execute("""CREATE TABLE google_scholar_cite_results (
                organic_results_title text, 
                organic_results_link text,
                citation_title text,
                citation_link text)""")
conn.commit()

# сохраняем органические результаты
for item in organic_results():
    conn.execute("""INSERT INTO google_scholar_organic_results
                    VALUES (:page_number,
                            :position,
                            :result_type,
                            :title,
                            :link,
                            :snippet,
                            :result_id,
                            :publication_info_summary,
                            :cited_by_count,
                            :cited_by_link,
                            :cited_by_id,
                            :total_versions,
                            :all_versions_link,
                            :all_versions_id,
                            :file_format,
                            :file_title,
                            :file_link)""",
                     {"page_number": item["page_number"],
                      "position": item["position"],
                      "result_type": item["type"],
                      "title": item["title"],
                      "link": item["link"],
                      "snippet": item["snippet"],
                      "result_id": item["result_id"],
                      "publication_info_summary": item["publication_info_summary"],
                      "cited_by_count": item["cited_by_count"],
                      "cited_by_link": item["cited_by_link"],
                      "cited_by_id": item["cited_by_id"],
                      "total_versions": item["total_versions"],
                      "all_versions_link": item["all_versions_link"],
                      "all_versions_id": item["all_versions_id"],
                      "file_format": item["file_format"],
                      "file_title": item["file_title"],
                      "file_link": item["file_link"]})
conn.commit()

# сохраняем цитируемые результаты
for cite_result in cite_results():
    conn.execute("""INSERT INTO google_scholar_cite_results 
                    VALUES (:organic_result_title,
                    :organic_result_link,
                    :citation_title,
                    :citation_snippet)""",
                 {"organic_result_title": cite_result["organic_result_title"],
                  "organic_result_link": cite_result["organic_result_link"],
                  "citation_title": cite_result["citation_title"],
                  "citation_snippet": cite_result["citation_snippet"]})

conn.commit()
conn.close() # явно лучше, чем неявно
Объяснение сохранения извлеченных данных вручную прописывая запросы SQLite

Импортируем sqlite3 библиотеку:

import sqlite3 

Соединяемся с существующей базе данных или даём новое имя и библиотека создаст базу данных:

conn = sqlite3.connect("google_scholar_results.db")

Создаём таблицу органические результаты, указываем тип данных и применяем изменения:

conn.execute("""CREATE TABLE google_scholar_organic_results (
                page_number integer,
                position integer,
                result_type text,
                title text, 
                link text,
                snippet text,
                result_id text,
                publication_info_summary text,
                cited_by_count integer,
                cited_by_link text,
                cited_by_id text,
                total_versions integer,
                all_versions_link text,
                all_versions_id text,
                file_format text,
                file_title text,
                file_link text)""")
conn.commit()

Создаём таблицу цитируемые результаты, указываем тип данных и применяем изменения:

conn.execute("""CREATE TABLE google_scholar_cite_results (
            organic_results_title text, 
            organic_results_link text,
            citation_title text,
            citation_link text)""")
conn.commit()

Добавляем извлеченные органические результаты в таблицу используя for цикл:

for item in organic_results():
    conn.execute("""INSERT INTO google_scholar_organic_results
                    VALUES (:page_number,
                            :position,
                            :result_type,
                            :title,
                            :link,
                            :snippet,
                            :result_id,
                            :publication_info_summary,
                            :cited_by_count,
                            :cited_by_link,
                            :cited_by_id,
                            :total_versions,
                            :all_versions_link,
                            :all_versions_id,
                            :file_format,
                            :file_title,
                            :file_link)""",
                     {"page_number": item["page_number"],
                      "position": item["position"],
                      "result_type": item["type"],
                      "title": item["title"],
                      "link": item["link"],
                      "snippet": item["snippet"],
                      "result_id": item["result_id"],
                      "publication_info_summary": item["publication_info_summary"],
                      "cited_by_count": item["cited_by_count"],
                      "cited_by_link": item["cited_by_link"],
                      "cited_by_id": item["cited_by_id"],
                      "total_versions": item["total_versions"],
                      "all_versions_link": item["all_versions_link"],
                      "all_versions_id": item["all_versions_id"],
                      "file_format": item["file_format"],
                      "file_title": item["file_title"],
                      "file_link": item["file_link"]})
conn.commit()

Добавляем извлеченные цитируемые результаты в таблицу используя for цикл:

for cite_result in cite_results():
    conn.execute("""INSERT INTO google_scholar_cite_results 
                    VALUES (:organic_result_title,
                    :organic_result_link,
                    :citation_title,
                    :citation_snippet)""",
                 {"organic_result_title": cite_result["organic_result_title"],
                  "organic_result_link": cite_result["organic_result_link"],
                  "citation_title": cite_result["citation_title"],
                  "citation_snippet": cite_result["citation_snippet"]})
conn.commit()

Закрываем cоединение с базой данных:

conn.close()

Дополнительные полезные команды:

# удалить все данные из таблицы
conn.execute("DELETE FROM google_scholar_organic_results")

# удалить таблицу
conn.execute("DROP TABLE google_scholar_organic_results")

# удалить колонку
conn.execute("ALTER TABLE google_scholar_organic_results DROP COLUMN authors")

# добавить колнку
conn.execute("ALTER TABLE google_scholar_organic_results ADD COLUMN snippet text")

Код целиком - парсинг

import os
from serpapi import GoogleSearch
from urllib.parse import urlsplit, parse_qsl


def organic_results():
    print("extracting organic results..")

    params = {
        "api_key": os.getenv("API_KEY"),
        "engine": "google_scholar",
        "q": "minecraft redstone system structure characteristics strength",  # поисковый запрос
        "hl": "en",        # язык
        "as_ylo": "2017",  # от 2017
        "as_yhi": "2021",  # до 2021
        "start": "0"
    }

    search = GoogleSearch(params)

    organic_results_data = []

    loop_is_true = True

    while loop_is_true:
        results = search.get_dict()

        print(f"Currently extracting page №{results['serpapi_pagination']['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")
    
            try:
              file_title = result["resources"][0]["title"]
            except: file_title = None
    
            try:
              file_link = result["resources"][0]["link"]
            except: file_link = None
    
            try:
              file_format = result["resources"][0]["file_format"]
            except: file_format = None
    
            try:
              cited_by_count = int(result["inline_links"]["cited_by"]["total"])
            except: cited_by_count = None
    
            cited_by_id = result.get("inline_links", {}).get("cited_by", {}).get("cites_id", {})
            cited_by_link = result.get("inline_links", {}).get("cited_by", {}).get("link", {})
    
            try:
              total_versions = int(result["inline_links"]["versions"]["total"])
            except: total_versions = None
    
            all_versions_link = result.get("inline_links", {}).get("versions", {}).get("link", {})
            all_versions_id = result.get("inline_links", {}).get("versions", {}).get("cluster_id", {})
    
            organic_results_data.append({
              "page_number": results["serpapi_pagination"]["current"],
              "position": position + 1,
              "result_type": result_type,
              "title": title,
              "link": link,
              "result_id": result_id,
              "publication_info_summary": publication_info_summary,
              "snippet": snippet,
              "cited_by_count": cited_by_count,
              "cited_by_link": cited_by_link,
              "cited_by_id": cited_by_id,
              "total_versions": total_versions,
              "all_versions_link": all_versions_link,
              "all_versions_id": all_versions_id,
              "file_format": file_format,
              "file_title": file_title,
              "file_link": file_link,
            })

            if "next" in results["serpapi_pagination"]:
                search.params_dict.update(dict(parse_qsl(urlsplit(results["serpapi_pagination"]["next"]).query)))
            else:
                loop_is_true = False

    return organic_results_data
    
    
def cite_results():

    print("extracting cite results..")

    citation_results = []

    for citation in organic_results():
        params = {
            "api_key": os.getenv("API_KEY"),
            "engine": "google_scholar_cite",
            "q": citation["result_id"]
        }

        search = GoogleSearch(params)
        results = search.get_dict()

        print(f"Currently extracting {citation['result_id']} citation ID.")

        for result in results["citations"]:
            cite_title = result["title"]
            cite_snippet = result["snippet"]

            citation_results.append({
                "organic_result_title": citation["title"],
                "organic_result_link": citation["link"],
                "citation_title": cite_title,
                "citation_snippet": cite_snippet
            })

    return citation_results



# пример вывода при парсинге органических результатов и сохранение в SQL:
'''
extracting organic results..
Currently extracting page №1..
Currently extracting page №2..
Currently extracting page №3..
Currently extracting page №4..
Currently extracting page №5..
Currently extracting page №6..
Done extracting organic results.
Saved to SQL Lite database.
'''

Код целиком - сохранение

import pandas as pd
import sqlite3
from google_scholar_organic_results import organic_results
from google_scholar_cite_results import cite_results

# Один из способов сохранить данные в БД используя Pandas
print("waiting for organic results to save..")
organic_df = pd.DataFrame(data=organic_results())
organic_df.to_csv("google_scholar_organic_results.csv", encoding="utf-8", index=False)

print("waiting for cite results to save..")
cite_df = pd.DataFrame(data=cite_results())
cite_df.to_csv("google_scholar_citation_results.csv", encoding="utf-8", index=False)

# ------------------------------

# Другой способ сохранить данные в БФ в ручную прописывая SQLite запросы
conn = sqlite3.connect("google_scholar_results.db")

conn.execute("""CREATE TABLE google_scholar_organic_results (
                page_number integer,
                position integer,
                result_type text,
                title text,
                link text,
                snippet text,
                result_id text,
                publication_info_summary text,
                cited_by_count integer,
                cited_by_link text,
                cited_by_id text,
                total_versions integer,
                all_versions_link text,
                all_versions_id text,
                file_format text,
                file_title text,
                file_link text)""")
conn.commit()


conn.execute("""CREATE TABLE google_scholar_cite_results (
            organic_results_title text,
            organic_results_link text,
            citation_title text,
            citation_link text)""")
conn.commit()

for item in organic_results():
    conn.execute("""INSERT INTO google_scholar_organic_results
                    VALUES (:page_number,
                            :position,
                            :result_type,
                            :title,
                            :link,
                            :snippet,
                            :result_id,
                            :publication_info_summary,
                            :cited_by_count,
                            :cited_by_link,
                            :cited_by_id,
                            :total_versions,
                            :all_versions_link,
                            :all_versions_id,
                            :file_format,
                            :file_title,
                            :file_link)""",
                 {"page_number": item["page_number"],
                  "position": item["position"],
                  "result_type": item["type"],
                  "title": item["title"],
                  "link": item["link"],
                  "snippet": item["snippet"],
                  "result_id": item["result_id"],
                  "publication_info_summary": item["publication_info_summary"],
                  "cited_by_count": item["cited_by_count"],
                  "cited_by_link": item["cited_by_link"],
                  "cited_by_id": item["cited_by_id"],
                  "total_versions": item["total_versions"],
                  "all_versions_link": item["all_versions_link"],
                  "all_versions_id": item["all_versions_id"],
                  "file_format": item["file_format"],
                  "file_title": item["file_title"],
                  "file_link": item["file_link"]})
conn.commit()


for cite_result in cite_results():
    conn.execute("""INSERT INTO google_scholar_cite_results
                    VALUES (:organic_result_title,
                    :organic_result_link,
                    :citation_title,
                    :citation_snippet)""",
                 {"organic_result_title": cite_result["organic_result_title"],
                  "organic_result_link": cite_result["organic_result_link"],
                  "citation_title": cite_result["citation_title"],
                  "citation_snippet": cite_result["citation_snippet"]})

conn.commit()
conn.close()
print("Saved to SQL Lite database.")


# пример вывода:
'''
extracting organic results..
Currently extracting page №1..
...
Currently extracting page №4..
extracting cite results..
extracting organic results..
Currently extracting page №1..
...
Currently extracting page №4..
Currently extracting 60l4wsP6Ps0J citation ID.
Currently extracting 9hkhIFu_BhAJ citation ID.
...
Saved to SQL Lite database.
'''

Ссылки


Что дальше

С этими данными должно быть возможно сделать какое-нибудь исследование, или визуализацию по определенной дисциплине. Классным дополнением к этому скрипту будет добавить возможность запускать его каждую неделю или месяц для парсинга дополнительных данных.

Следующий блог пост будет о парсинге Профилей с пагинацией, а так же Авторских результатов.

Если вы хотите парсить данные без необходимости писать парсер с нуля, разбираться как обойти блокировки от поисковых систем, как увеличить объем запросов, или, как парсить данные с JavaScript - попробуйте SerpApi или свяжитесь с SerpApi.


Присоединяйтесь к нам на Reddit | Twitter | YouTube

Теги:
Хабы:
Всего голосов 6: ↑6 и ↓0+6
Комментарии8

Публикации

Истории

Работа

Data Scientist
60 вакансий
Python разработчик
136 вакансий

Ближайшие события