Почему я получаю повторяющиеся данные при попытке очистить данные из Google Scholar?

Я пытаюсь очистить ссылки PDF из результатов поиска Google Scholar. Я пытался установить счетчик страниц на основе изменения URL-адреса, но после первых восьми выходных ссылок я получаю повторяющиеся ссылки в качестве вывода.

#!/usr/bin/env python
from mechanize import Browser
from BeautifulSoup import BeautifulSoup
from bs4 import BeautifulSoup
import urllib2
import requests


#modifying the url as per page
urlCounter = 0
while urlCounter <=30:
    urlPart1 = "http://scholar.google.com/scholar?start="
    urlPart2 = "&q=%22entity+resolution%22&hl=en&as_sdt=0,4"
    url = urlPart1 + str(urlCounter) + urlPart2
    page = urllib2.Request(url,None,{"User-Agent":"Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"})
    resp = urllib2.urlopen(page)
    html = resp.read()
    soup = BeautifulSoup(html)
    urlCounter = urlCounter + 10

    recordCount = 0
    while recordCount <=9:
        recordPart1 = "gs_ggsW"
        finRecord = recordPart1 + str(recordCount)
        recordCount = recordCount+1

    #printing the links
        for link in soup.find_all('div', id = finRecord):
            linkstring = str(link)
            soup1 = BeautifulSoup(linkstring)
        for link in soup1.find_all('a'):
            print(link.get('href'))

2 ответа

Решение

Измените следующую строку в вашем коде:

finRecord = recordPart1 + str(recordCount)

к

finRecord = recordPart1 + str(recordCount+urlCounter-10)

Реальная проблема: идентификаторы div на первой странице - это gs_ggsW[0-9], а идентификаторы на второй странице - gs_ggsW[10-19]. Так что красивый суп не найдет ссылок на 2-й странице.

Область видимости переменных Python может сбить с толку людей из других языков, таких как Java. После выполнения цикла for ниже, переменная link все еще существует. Таким образом, ссылка ссылается на последнюю ссылку на 1-й странице.

for link in soup1.find_all('a'):
    print(link.get('href'))

Обновления:

Google может не предоставлять ссылки на скачивание PDF для некоторых статей, поэтому вы не можете использовать идентификатор, чтобы соответствовать ссылке на каждую статью. Вы можете использовать селекторы CSS, чтобы сопоставить все ссылки вместе.

soup = BeautifulSoup(html)
urlCounter = urlCounter + 10
for link in soup.select('div.gs_ttss a'):
    print(link.get('href'))

Взгляните на расширение SelectorGadget Chrome, чтобы получить CSSселекторы, щелкнув нужный элемент в браузере.

Код и пример в онлайн-среде IDE для извлечения PDF-файлов:

      from bs4 import BeautifulSoup
import requests, lxml

params = {
    "q": "entity resolution", # search query
    "hl": "en"                # language
}

# https://requests.readthedocs.io/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/72.0.3538.102 Safari/537.36 Edge/18.19582",
}

html = requests.get("https://scholar.google.com/scholar", params=params, headers=headers, timeout=30)
soup = BeautifulSoup(html.text, "lxml")

for pdf_link in soup.select(".gs_or_ggsm a"):
  pdf_file_link = pdf_link["href"]
  print(pdf_file_link)


# output from the first page:
'''
https://linqs.github.io/linqs-website/assets/resources/getoor-vldb12-slides.pdf
http://ilpubs.stanford.edu:8090/859/1/2008-7.pdf
https://drum.lib.umd.edu/bitstream/handle/1903/4241/umi-umd-4070.pdf;sequence=1
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.169.9535&rep=rep1&type=pdf
https://arxiv.org/pdf/1208.1927
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.77.6875&rep=rep1&type=pdf
http://da.qcri.org/ntang/pubs/vldb18-deeper.pdf
'''

Кроме того, вы можете добиться того же, используя Google Scholar Organic Results API от SerpApi. Это платный API с бесплатным планом.

Основное отличие состоит в том, что вам нужно получить данные только из структурированного JSON вместо того, чтобы выяснять, как извлечь данные из HTML, как обойти блокировку поисковых систем.

Код для интеграции:

      from serpapi import GoogleSearch

params = {
    "api_key": "YOUR_API_KEY",   # SerpApi API key
    "engine": "google_scholar",  # Google Scholar organic reuslts
    "q": "entity resolution",    # search query
    "hl": "en"                   # language
}

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

for pdfs in results["organic_results"]:
    for link in pdfs.get("resources", []):
        pdf_link = link["link"]
        print(pdf_link)


# output:
'''
https://linqs.github.io/linqs-website/assets/resources/getoor-vldb12-slides.pdf
http://ilpubs.stanford.edu:8090/859/1/2008-7.pdf
https://drum.lib.umd.edu/bitstream/handle/1903/4241/umi-umd-4070.pdf;sequence=1
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.169.9535&rep=rep1&type=pdf
https://arxiv.org/pdf/1208.1927
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.77.6875&rep=rep1&type=pdf
http://da.qcri.org/ntang/pubs/vldb18-deeper.pdf
'''

Если вы хотите извлечь больше данных из обычных результатов, есть специальная запись в блоге Scrape Google Scholar with Python.

Отказ от ответственности, я работаю в SerpApi.

Другие вопросы по тегам