Объединить разбор html внутри и снаружи iframe с BeautifulSoup - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь соскрести с сайта о недвижимости, используя Selenium / BS4 / Python. Сценарий извлекает ссылки на страницы со списком перед анализом html на каждой странице со списком. Я использую расширение Chrome под названием Property Data, которое отображается в виде iframe на каждой странице и отображает данные для конкретной области, в которой находится листинг (например, средние цены, доходность и т. Д. c для этого почтового индекса / почтового индекса). Требуется около 15 секунд, чтобы загрузить результаты на каждой странице списка. Пожалуйста, смотрите скриншот расширения в правой части страницы:
https://imgur.com/a/mjodyts

iframe html из Chrome проверять:

<div class="row one-col print-hidden"><div class="cell"><div class="module"><div class="hl-1 pad-16" style="padding-top: 0 !important;"><div class="propertydata" style="height: 410px; overflow: none;"><iframe scrolling="no" style="width: 302px; height: 410px; margin: 0; border: 0;" src="https://propertydata.co.uk/extension/1.3/51.579520/-0.235261/rightmove/78617383/399950/2"></iframe></div></div></div></div></div>

Мой вопрос:
Как только iframe и результаты расширения chrome загружены на страницу листинга, как мне изменить функцию get_html_data в приведенном ниже коде, чтобы она сначала анализировала html существующей страницы, а затем переключается на разбор и размещение элементов в iframe?

rightmove_hmo_search = "https://www.rightmove.co.uk/property-for-sale/find.html?locationIdentifier=POSTCODE%5E1619792&maxBedrooms=4&minBedrooms=2&maxPrice=500000&radius=10.0&sortType=18&propertyTypes=&maxDaysSinceAdded=14&includeSSTC=false&mustHave=&dontShow=newHome%2CsharedOwnership%2Cretirement&furnishTypes=&keywords=stpp%2Cloft"

#identify and extract listing links from each page (in this case first page only)
def get_house_links(url, driver, pages=1):
    house_links = []
    driver.get(url)
    for i in range(pages):
        soup = BeautifulSoup(driver.page_source, 'html.parser')
        listings = soup.find_all("a", class_="propertyCard-moreInfoItem is-carousel")
        page_data = ['https://rightmove.co.uk' + row['href'] for row in listings]
        house_links.append(page_data)
        print(house_links)
       # next_button = soup.select('button[class="pagination-button pagination-direction pagination-direction--next"]')
       # if next_button:
         #   for page in range(0, 1):
        #        index = page * 24
        #        next_button_link = 'https://www.rightmove.co.uk/property-for-sale/find.html?locationIdentifier=POSTCODE%5E1619792&maxBedrooms=4&minBedrooms=2&maxPrice=500000&radius=10.0&sortType=18&' + '&index=' + str(index) + '&propertyTypes=&maxDaysSinceAdded=14&includeSSTC=false&mustHave=&dontShow=newHome%2CsharedOwnership%2Cretirement&furnishTypes=&keywords=stpp%2Cloft'
         #       driver.get(next_button_link)
         #       if page > 1:
          #          break


    return house_links


#get html data from url and return as object
def get_html_data(url, driver):
    driver.get(url)
    try:
        WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.XPATH, "//iframe[contains(@class, 'key')]")))
    except TimeoutException:
        print("page took too long to load")
    BeautifulSoup(driver.page_source, 'html.parser')
    driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
    time.sleep(3)
    soup = BeautifulSoup(driver.page_source, 'html.parser')

    return soup

1 Ответ

1 голос
/ 14 апреля 2020

Я не знаю, почему вы даже используете selenium, к вашему сведению, данные уже находятся внутри источника page под тегом script. поэтому вам даже не нужно собирать urls, а затем l oop для доступа к каждому из них.

Все это можно сделать за один вызов!

I ' мы загрузили его в JSON dict, так что вы можете получить к нему доступ и проанализировать все, что вам нужно.

import requests
import re
import json


def main(url):
    r = requests.get(url)
    match = re.search(r"window.jsonModel = ({.+})", r.text).group(1)
    data = json.loads(match)
    hview = json.dumps(data, indent=4)
    print(data.keys())
    print(hview)


main("https://www.rightmove.co.uk/property-for-sale/find.html?locationIdentifier=POSTCODE%5E1619792&maxBedrooms=4&minBedrooms=2&maxPrice=500000&radius=10.0&sortType=18&propertyTypes=&maxDaysSinceAdded=14&includeSSTC=false&mustHave=&dontShow=newHome%2CsharedOwnership%2Cretirement&furnishTypes=&keywords=stpp%2Cloft")

Вывод:

dict_keys(['properties', 'resultCount', 'searchParametersDescription', 'radiusOptions', 'priceOptions', 'bedroomOptions', 'addedToSiteOptions', 'mustHaveOptions', 'dontShowOptions', 'furnishOptions', 'letTypeOptions', 'sortOptions', 'applicationProperties', 'staticMapUrl', 'shortLocationDescription', 'timestamp', 'bot', 'deviceType', 'propertySchema', 'sidebarModel', 
'seoModel', 'mapViewUrl', 'legacyUrl', 'listViewUrl', 'pageTitle', 'metaDescription', 'recentSearchModel', 'maxCardsPerPage', 'countryCode', 'countryId', 'currencyCodeOptions', 'areaSizeUnitOptions', 'sizeOptions', 'priceTypeOptions', 'showFeaturedAgent', 'showNewDrawASearch', 'commercialChannel', 'disambiguationPagePath', 'dfpModel', 'noResultsModel', 'urlPath', 'tileGeometry', 'geohashTerms', 'comscore', 'cookiePolicies', 'formattedExchangeRateDate', 'authenticated', 'location', 'searchParameters', 'featureSwitchStateForUser', 'pagination'])

В этой клавише находятся нужные данные properties :

Например, это первое предложение:

"properties": [
        {
            "id": 78658603,
            "bedrooms": 2,
            "numberOfImages": 10,
            "numberOfFloorplans": 1,
            "numberOfVirtualTours": 0,
            "summary": "Presented in outstanding condition, this gorgeous 2 bedroom apartment is set within a modern development and offers a bright open-plan reception room/kitchen, excellent fixtures and a charming private Balcony.",
            "displayAddress": "Haydons Road, Wimbledon, London, SW19",
            "countryCode": "GB",
            "location": {
                "latitude": 51.42015,
                "longitude": -0.187532
            },
            "propertySubType": "Flat",
            "listingUpdate": {
                "listingUpdateReason": "new",
                "listingUpdateDate": "2020-04-03T11:08:02Z"
            },
            "premiumListing": false,
            "featuredProperty": true,
            "price": {
                "amount": 500000,
                "frequency": "not specified",
                "currencyCode": "GBP",
                "displayPrices": [
                    {
                        "displayPrice": "\u00a3500,000",
                        "displayPriceQualifier": ""
                    }
                ]
            },
            "customer": {
                "branchId": 15975,
                "brandPlusLogoURI": "/company/clogo_rmchoice_5187_0012.jpeg",
                "contactTelephone": "020 8012 6808",
                "branchDisplayName": "Foxtons, Wimbledon",
                "branchName": "Wimbledon",
                "brandTradingName": "Foxtons",
                "branchLandingPageUrl": "/estate-agents/agent/Foxtons/Wimbledon-15975.html",
                "development": false,
                "showReducedProperties": true,
                "commercial": false,
                "showOnMap": true,
                "brandPlusLogoUrl": "https://media.rightmove.co.uk:443/dir/company/clogo_rmchoice_5187_0012_max_100x50.jpeg"
            },
            "distance": 8.0669,
            "transactionType": "buy",
            "productLabel": {
                "productLabelText": ""
            },
            "commercial": false,
            "development": false,
            "residential": true,
            "students": false,
            "auction": false,
            "feesApply": false,
            "feesApplyText": null,
            "displaySize": "",
            "showOnMap": true,
            "propertyUrl": "/property-for-sale/property-78658603.html",
            "contactUrl": "/property-for-sale/contactBranch.html?propertyId=78658603",
            "channel": "BUY",
            "firstVisibleDate": "2020-04-03T11:02:42Z",
            "keywords": [
                {
                    "keyword": "stpp",
                    "matched": false
                },
                {
                    "keyword": "loft",
                    "matched": false
                }
            ],
            "keywordMatchType": "no_match",
            "saved": null,
            "hidden": null,
            "onlineViewingsAvailable": false,
            "propertyImages": {
                "images": [
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_02_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_02_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_01_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_01_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_03_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_03_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_04_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_04_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_05_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_05_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_06_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_06_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_07_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_07_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_08_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_08_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_09_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_09_0000.jpg"
                    },
                    {
                        "srcUrl": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_10_0000_max_476x317.jpg",
                        "url": "16k/15975/78658603/15975_1130605_IMG_10_0000.jpg"
                    }
                ],
                "mainImageSrc": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_02_0000_max_476x317.jpg",
                "mainMapImageSrc": "https://media.rightmove.co.uk:443/dir/crop/10:9-16:9/16k/15975/78658603/15975_1130605_IMG_02_0000_max_296x197.jpg"
            },
            "displayStatus": "",
            "formattedBranchName": " by Foxtons, Wimbledon",
            "addedOrReduced": "Added on 03/04/2020",
            "isRecent": false,
            "formattedDistance": "8.07 miles",
            "heading": "Featured Property",
            "hasBrandPlus": true,
            "propertyTypeFullDescription": "2 bedroom flat for sale"
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...