Как можно использовать селекторы Dynami c css с Beautiful Soup? - PullRequest
1 голос
/ 07 августа 2020

Следующий код извлекает данные из определенных c селекторов для сайтов в siteUrlArray. Работает нормально.

Однако для этого мне нужно написать по одной функции для каждого веб-сайта - просто для определения селекторов. Я пытаюсь динамически построить soup.find и soup.select, используя exe c и dict для хранения переменных селектора, но не могу заставить его работать.

Рабочий код

from bs4 import BeautifulSoup
import requests
import sys
import tldextract

def processmarketbeat(soup):
    try:
        mbtSel = soup.findAll("div", {"id": "cphPrimaryContent_tabAnalystRatings"})[0].find("table")
        print(mbtSel)
    except Exception as e:
        print(str(e))
        
def processwsj(soup):
    try:
        wsjSel = soup.select('.at8-col4 > .zonedModule')[0]
        print(wsjSel)
    except Exception as e:
        print(str(e))

global siteUrl, domain, header, parser
header = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0',}
parser = 'html.parser'

siteUrlArray = ['http://www.marketbeat.com/stocks/NASDAQ/GOOGL/price-target', 
                'http://www.wsj.com/market-data/quotes/GOOGL/research-ratings', 
                'http://www.marketbeat.com/stocks/NASDAQ/SQ/price-target', 
                'http://www.wsj.com/market-data/quotes/SQ/research-ratings']

for i in range(len(siteUrlArray)):
    siteUrl = siteUrlArray[i]   
    parsedUrl = tldextract.extract(siteUrl)
    domain = parsedUrl.domain

    r = requests.get(siteUrl, headers=header, verify=False)
    soup = BeautifulSoup(r.text, parser)
    getattr(sys.modules[__name__], "process%s" % domain)(soup)

Попытка использовать динамический c селектор

stockDict = {
    'marketbeat': '"""x = soup.findAll("div", {"id": "cphPrimaryContent_tabAnalystRatings"})[0].find("table")"""',
    'wsj': '"""x = soup.select(".at8-col4 > .zonedModule")[0]"""'
}

header = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0',}
parser = 'html.parser'

siteUrlArray = ['http://www.marketbeat.com/stocks/NASDAQ/GOOGL/price-target', 
                'http://www.wsj.com/market-data/quotes/GOOGL/research-ratings', 
                'http://www.marketbeat.com/stocks/NASDAQ/SQ/price-target', 
                'http://www.wsj.com/market-data/quotes/SQ/research-ratings']

for i in range(len(siteUrlArray)):
    siteUrl = siteUrlArray[i]   
    parsedUrl = tldextract.extract(siteUrl)
    domain = parsedUrl.domain

    r = requests.get(siteUrl, headers=header, verify=False)
    soup = BeautifulSoup(r.text, parser)

    selector = stockDict.get(domain)
    exec(selector) 
    # I want the EXEC to run the equivalent of
    # x = soup.findAll("div", {"id": "cphPrimaryContent_tabAnalystRatings"})[0].find("table")
    # so that I can print the tags as print(x)
    print(x)

Но x печатается как None вместо HTML кода выбранных объектов.

1 Ответ

1 голос
/ 07 августа 2020

Мне удалось добиться того, что я намеревался сделать, с помощью следующего кода:

selectorDict = {
    'marketbeat': 'x = soup.findAll("div", {"id": "cphPrimaryContent_tabAnalystRatings"})[0].find("table")\nprint(x)',
    'wsj': 'x = soup.select(".at8-col4 > .zonedModule")[0]\nprint(x)'
}

for i in range(len(siteUrlArray)):
    siteUrl = siteUrlArray[i]   
    print(siteUrl)
    parsedUrl = tldextract.extract(siteUrl)
    domain = parsedUrl.domain

    r = requests.get(siteUrl, headers=header, verify=False)
    soup = BeautifulSoup(r.text, parser)

    selector = selectorDict.get(domain)
    try:
        exec(selector) 
    except Exception as e:
        print(str(e))        
...