Beautifulsoup "findAll ()" не возвращает теги - PullRequest
1 голос
/ 21 сентября 2019

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

Проблема в том, что мой for link in bsObj.findAll('a',{'class':'search-track'}) не возвращает ссылки, необходимые для дальнейшей сборки моего скребка.В моем коде проверка выглядит следующим образом:

for link in bsObj.findAll('a',{'class':'search-track'}):
     print(link)

Приведенный выше цикл for ничего не печатает, однако ссылки href должны находиться внутри <a class="search-track" ...</a>.

Iупомянул этот пост , но изменение парсера Beautifulsoup не решает проблему моего кода.Я использую "html.parser" в моем конструкторе Beautifulsoup: bsObj = bs(html.content, features="html.parser").

И print(len(bsObj)) выводит «3», в то время как выводит «2» для "lxml" и "html5lib".

Кроме того, я начал использовать urllib.request.urlopen, чтобы получитьстраницу, а затем попытался requests.get() вместо этого.К сожалению, оба подхода дают мне одно и то же bsObj.

Вот код, который я написал:

#from urllib.request import urlopen
import requests
from bs4 import BeautifulSoup as bs
import ssl


'''
The elsevier search is kind of a tree structure:
"keyword --> a list of journals (a journal contain many articles) --> lists of articles
'''
address = input("Please type in your keyword: ") #My keyword is catalyst for water splitting
#https://www.elsevier.com/en-xs/search-results? 
#query=catalyst%20for%20water%20splitting&labels=journals&page=1
address = address.replace(" ", "%20")
address = "https://www.elsevier.com/en-xs/search-results?query=" + address + "&labels=journals&page=1"

journals = []
articles = []

def getJournals(url):
    global journals

    #html = urlopen(url)
    html = requests.get(url)
    bsObj = bs(html.content, features="html.parser")

    #print(len(bsObj))
    #testFile = open('testFile.txt', 'wb')
    #testFile.write(bsObj.text.encode(encoding='utf-8', errors='strict') +'\n'.encode(encoding='utf-8', errors='strict'))
    #testFile.close()

    for link in bsObj.findAll('a',{'class':'search-track'}):
        print(link) 
        ########does not print anything########
        '''
        if 'href' in link.attrs and link.attrs['href'] not in journals:
            newJournal = link.attrs['href']
            journals.append(newJournal)
        '''
    return None


# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

getJournals(address)
print(journals)

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

1 Ответ

0 голосов
/ 21 сентября 2019

Эта страница динамически загружается с помощью jscript, поэтому Beautifulsoup не может обработать ее напрямую.Вы можете сделать это с помощью Selenium, но в этом случае вы можете сделать это, отслеживая вызовы API, сделанные страницей (, подробнее см. Здесь, в качестве одного из многих примеров.

В вашем конкретном случае это можно сделать следующим образом:

from bs4 import BeautifulSoup as bs
import requests
import json

#this is where the data is hiding:
url = "https://site-search-api.prod.ecommerce.elsevier.com/search?query=catalyst%20for%20water%20splitting&labels=journals&start=0&limit=10&lang=en-xs"
html = requests.get(url)
soup = bs(html.content, features="html.parser")


data = json.loads(str(soup))#response is in json format so we load it into a dictionary

Примечание: в этом случае также можно полностью отказаться от Beautifulsoup и загрузить ответ напрямую, как в data = json.loads(html.content).точка:

hits = data['hits']['hits']#target urls are hidden deep inside nested dictionaries and lists
for hit in hits:
    print(hit['_source']['url'])

Выход:

https://www.journals.elsevier.com/water-research
https://www.journals.elsevier.com/water-research-x

и т. д.

...