Selenium + BS, Парсинг: проблема с извлечением текста из - PullRequest
0 голосов
/ 16 июня 2020

ОБНОВЛЕНИЕ: я исправил несколько синтаксических ошибок (мне не удалось запустить скрипт, потому что я сделал слишком много запросов за короткое время, поэтому я боялся запускать снова). Код обновлен, но проблема все еще существует.

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

ПРИМЕЧАНИЕ. Данные не будут использоваться после тестирования.

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

Проблема в том, что, как только я использовал красивый суп для выбора объекта скрипта в форме

<script type="application/ld+json">
    {"@type":"SingleFamilyResidence","@context":"http://schema.org","name":"6012 Briscoe Ln, Louisville, KY 40228","floorSize":{"@type":"QuantitativeValue","@context":"http://schema.org","value":"1,555"},"address":{"@type":"PostalAddress","@context":"http://schema.org","streetAddress":"6012 Briscoe Ln ","addressLocality":"Louisville","addressRegion":"KY","postalCode":"40228"},"geo":{"@type":"GeoCoordinates","@context":"http://schema.org","latitude":38.14154,"longitude":-85.648248},"url":"https://www.zillow.com/homedetails/6012-Briscoe-Ln-Louisville-KY-40228/73554517_zpid/"}</script>

, я получаю пустую строку при использовании атрибута .text, поэтому, когда я go, чтобы загрузить его как json, чтобы сохранить словарь между тегами скрипта, я получаю сообщение об ошибке, указывающее, что значение ожидалось.

Входной файл zips.csv имеет формат csv.

имя файла: zips.csv 40223,40214,40228,40219,40241,40206,40220,40212,40206,40210 , 40213,40203,40213,40208,40272,40220,40222

Это одна строка с каждым почтовым индексом, разделенным запятой (как указано csv).

Вот мой код для продемонстрировать, что я делаю; Веб-сайт (указанный в коде как baseUrl) - это то, что меня интересует. Я добавляю почтовый индекс к URL-адресу, чтобы получить страницу домов в этом почтовом индексе. Даже когда я использую test I в качестве источника для конструктора BeautifulSoup, я получаю тот же результат. Если вы закомментируете строки с помощью # D и раскомментируете альтернативные source и homes, вы увидите это.

def configure_driver():
    chrome_options = Options()
    #chrome_options.add_argument('--headless')
    driver = webdriver.Chrome()
    return driver 

def gen_searchers(driver):
    print('gen searchers')

    baseUrl2 = "https://www.zillow.com/homes/"
    selector2 = ".photo-cards"

    driver.get(baseUrl2) # D

    # sometimes captcha pops up, so get around quick polling
    WebDriverWait(driver,115).until(lambda s: s.find_element_by_css_selector(selector2)) # D

    # wait for housing list to load
    zips = []
    addy_all_zips = []

    try: 
        with open('zips.csv','r') as file:
            zips = file.readline().split(',')
    except:
        print('file not found\n')
    else:
        # for each zipcode in zips
        for z in zips:
            mainUrl2 = baseUrl2 + z +'_rb/'

            # scrape web dom
            driver.get(mainUrl2) #D
            try: 
                WebDriverWait(driver,10).until(lambda s: s.find_element_by_css_selector(selector2)) #D

                addy_one_zip = [] 
                source = driver.page_source #D
                #source = '<script type="application/ld+json">{"@type":"SingleFamilyResidence","@context":"http://schema.org","name":"6012 Briscoe Ln, Louisville, KY 40228","floorSize":{"@type":"QuantitativeValue","@context":"http://schema.org","value":"1,555"},"address":{"@type":"PostalAddress","@context":"http://schema.org","streetAddress":"6012 Briscoe Ln ","addressLocality":"Louisville","addressRegion":"KY","postalCode":"40228"},"geo":{"@type":"GeoCoordinates","@context":"http://schema.org","latitude":38.14154,"longitude":-85.648248},"url":"https://www.zillow.com/homedetails/6012-Briscoe-Ln-Louisville-KY-40228/73554517_zpid/"}</script>'
                soup = BeautifulSoup(source, 'html.parser')
                homes_list = soup.select_one("ul.photo-cards > li") #D
                homes = homes_list.select_one("script[type='application/ld+json']") #D

                # homes = soup.find("script",{"type": "application/ld+json"})
                print(homes) # PRINTS <script ....> ... </script>
                print(homes.text) # PRINTS string with no text
                print()

                # write data out and look at format
                with open("testpage.html", 'w') as file:
                    file.write(str(homes))
                    print('written')

                # ERROR ON THIS LINE (LOADING)
                js = json.loads(homes.text) 


                # TO PREVENT LOADING PAGES FOR EACH ZIP, JUST TRY ON ONE
                break
            except TimeoutException as err:
                print(err)

Я действительно не уверен в проблеме. Когда я исследую свою проблему, я нахожу информацию о том, как извлекать текст между тегами сценария (где тип - ld json), но мне это не удалось, несмотря на то, что я воспроизвел то, что сделали другие, и имел правильный тег сценария для выполнения операции.

1 Ответ

1 голос
/ 16 июня 2020

Вот как вы можете сделать это, если вы еще не заблокированы этим сайтом. Я использовал 40223 в качестве демонстрации, которая в конечном итоге формирует этот URL-адрес https://www.zillow.com/homes/40223_rb/:

import json
import requests
from bs4 import BeautifulSoup

link = "https://www.zillow.com/homes/40223_rb/"

res = requests.get(link,headers={"User-Agent":"Mozilla/5.0"})
soup = BeautifulSoup(res.text,"lxml")
for homes in soup.select("script[type='application/ld+json']"):
    home_url = json.loads(homes.get_text(strip=True))['url']
    print(home_url)

Первые несколько результатов выглядят примерно так:

https://www.zillow.com/homedetails/9903-Windfall-Trce-Louisville-KY-40223/73495241_zpid/
https://www.zillow.com/homedetails/2001-Ben-Ali-Rd-Louisville-KY-40223/73476052_zpid/
https://www.zillow.com/homedetails/321-Piatt-Pl-UNIT-102-Louisville-KY-40223/2079132587_zpid/
https://www.zillow.com/community/enclave-at-douglass-hills/2085942117_zpid/
https://www.zillow.com/community/enclave-at-douglass-hills/2085942119_zpid/
https://www.zillow.com/community/enclave-at-douglass-hills/2085942118_zpid/
...