Как получить больше данных - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь скачать все алмазы, которые у них есть, на следующем сайте: https://www.bluenile.com/diamond-search?tag=none&track=NavDiaVAll

План состоит в том, чтобы взять информацию и попытаться выяснить, какой из них мой любимый купить (я сделаю несколько регрессий, чтобы выяснить, какие из них имеют большую ценность, и выберу мой любимый)

Для этого я написал свой первый скребок. Проблема в том, что он берет только первые 60 бриллиантов вместо всего, что я вижу на сайте. В идеале я бы хотел, чтобы он взял все 100 000+ бриллиантов разных типов, которые у них есть (круглые, подушки и т. Д.). Как мне получить все данные?

(я думаю, это потому, что некоторые новые строки загружаются только после того, как я прокручиваю вниз, но я думаю, что более чем 60 загружаются с 1-го хода, и если я прокручиваю вниз до дна, он показывает только 1000)

Вот мой код:

import pandas as pd
import requests
from bs4 import BeautifulSoup

url = 'https://www.bluenile.com/diamond-search?tag=none&track=NavDiaVAll'

url_response = requests.get(url)
soup = BeautifulSoup(url_response.content, "html.parser")

""" Now we have the page as soup

Lets start to get the header"""

headerinctags = soup.find_all('div', class_='grid-header normal-header')
header = headerinctags[0].get_text(';')

diamondsmessy = soup.find_all('a', class_='grid-row row ')
diamondscleaned = diamondsmessy[1].get_text(";")


"""Create diamonds dataframe with the header; take out the 1st value"""
header = header.split(";")
del header[0]
diamonds = pd.DataFrame(columns=header)

""" place rows into dataframe after being split; use a & b as dummy variables; take out 5th value"""

for i in range(len(diamondsmessy)):
    a = diamondsmessy[i].get_text(";")
    b = a.split(";")
    del b[4]
    a = pd.DataFrame(b, index=header)
    b = a.transpose()
    diamonds = pd.concat([diamonds, b], ignore_index=True)

print(diamonds)

1 Ответ

0 голосов
/ 27 октября 2018

Я понял, как это сделать. Это не быстро, но по сути мне нужен селен, чтобы прокрутить страницу вниз. Я все еще застреваю с 1000 строками, поэтому что-то зациклило, чтобы обновить страницу.

Чтобы помочь другим, код здесь:

import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time

#for fun, let's time this
start = time.time()

"""Define important numbers"""

scroll_pauze_time = 0.5 #delay after scroll
scroll_number = 20 #number of times scrolled per page
pages_visited = 25 #number of times the price is increased

"""Set up the website"""

url = 'https://www.bluenile.com/diamond-search?tag=none&track=NavDiaVAll'

url_response = webdriver.Firefox()
url_response.get(url)

#minimum & max carat:
min_carat = url_response.find_element_by_css_selector('.carat-filter .allowHighAscii:nth-child(1)')
min_carat.send_keys('0.8')
min_carat.send_keys(Keys.ENTER)

max_carat = url_response.find_element_by_css_selector('.carat-filter .allowHighAscii:nth-child(2)')
max_carat.send_keys('1.05')
max_carat.send_keys(Keys.ENTER)


#Shapes of diamonds:
url_response.find_element_by_css_selector('.shape-filter-button:nth-child(2) > .shape-filter-button-inner').click()
url_response.find_element_by_css_selector('.shape-filter-button:nth-child(4) > .shape-filter-button-inner').click()
url_response.find_element_by_css_selector('.shape-filter-button:nth-child(5) > .shape-filter-button-inner').click()
url_response.find_element_by_css_selector('.shape-filter-button:nth-child(7) > .shape-filter-button-inner').click()

"""Create diamonds dataframe with the header; take out the 1st value"""
soup = BeautifulSoup(url_response.page_source, "html.parser")

headerinctags = soup.find_all('div', class_='grid-header normal-header')
header = headerinctags[0].get_text(';')

header = header.split(";")
del header[0]
diamonds = pd.DataFrame(columns=header)

"""Start loop, dummy variable j"""
for j in range(pages_visited):

    print(j)
    url_response.execute_script("window.scrollTo(0, 0)")

    #Set the minimum price
    if j != 0:
        min_price = url_response.find_element_by_css_selector('input[name="minValue"]')

        min_price.send_keys(Keys.CONTROL,"a");
        min_price.send_keys(Keys.DELETE);

        a = diamonds.loc[len(diamonds.count(1))-1,"Price"]
        a = a.replace('$','')
        a = a.replace(',','')
        min_price.send_keys(a)
        min_price.send_keys(Keys.ENTER)

    #Scroll down
    for i in range(scroll_number):
            url_response.execute_script("window.scrollTo(0, "+str((i+1)*2000)+')')
            time.sleep(scroll_pauze_time)

    #Grab data
    soup = BeautifulSoup(url_response.page_source, "html.parser")
    diamondsmessy = soup.find_all('a', class_='grid-row row ')


    """ place rows into dataframe after being split; use a & b as dummy variables; take out 5th value"""

    for i in range(len(diamondsmessy)):
        a = diamondsmessy[i].get_text(";")
        b = a.split(";")
        del b[4]
        a = pd.DataFrame(b, index=header)
        b = a.transpose()
        diamonds = pd.concat([diamonds, b], ignore_index=True)

diamonds = diamonds.drop_duplicates()
diamonds.to_csv('diamondsoutput.csv')

print(diamonds)

end = time.time()
print("This took "+ str(end-start)+" seconds")
...