Python, Pandas, Selenium добавляет / вставляет нули в пустые ячейки - PullRequest
0 голосов
/ 03 августа 2020

Это для моего личного проекта. Я использую операционную систему Windows 10. Я использую среду разработки pycharm. Я кодирую python и использую библиотеки селена и pandas.

Некоторые вещи, которые я пробовал: list.insert(k, '0') в for l oop перед всеми операторами if, np.where(pd.isnull(df)) после создания фрейма данных и if df.empty: df.append('0'). Я попробовал [0] * num_page_items, но получилось очень запутаться. Я решил go маршрут серии, потому что я читал, что NaN будет помещено в пустые ячейки, но это не сработало, как я планировал. Когда я попытался использовать фрейм данных, это не сработало, потому что массивы не одинакового размера.

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

What my current code gives me Current results

Что я хочу Чего я хочу достичь

Вот мой код.

# Import libraries
import time
from selenium import webdriver
import pandas as pd

# Open the google chrome browser and navigate to website
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(executable_path=PATH)

# Total amount of pages to web scrape
MAX_PAGE_NUM = 4

# Initialize lists
half = list()
oneg = list()
eighth = list()
quarter = list()
half = list()
oneoz = list()
each = list()

# Iterate through the pages and web scrape
for i in range(1, MAX_PAGE_NUM + 1):
    url = "https://weedmaps.com/deliveries/callweed-2?page=" + str(i)
    driver.get(url)
    print(url)

    # Find the elements by using xpath
    product_name = driver.find_elements_by_xpath('//div[@class ="styled-components__Name-sc-186ferk-9 lbdlVL"]')
    product_type = driver.find_elements_by_xpath('//span[@class ="styled-components__BrandCategory-sc-186ferk-6 dTklNg"]')
    prices = driver.find_elements_by_xpath('//span[@class="styled-components__Price-sc-6ubro-3 dEwZFC"]')
    weight = driver.find_elements_by_xpath('//div[@class="src__Box-sc-1sbtrzs-0 src__Flex-sc-1sbtrzs-1 styled-components__UnitLabel-sc-6ubro-1 dGTmZk"]')
    wordEach = driver.find_elements_by_xpath('//div[@class="src__Box-sc-1sbtrzs-0 src__Flex-sc-1sbtrzs-1 styled-components__UnitLabel-sc-6ubro-1 dGTmZk"]')

    # Get the length of the products
    num_page_items = len(product_name)

    # Store the product names and the types in respective lists
    products = [product_name[j].text for j in range(num_page_items)]
    types = [product_type[j].text for j in range(num_page_items)]

   # Append prices to respective lists
    for k in range(num_page_items):
        if weight[k].text == '1/2 g':
            half.append(prices[k].text)
        elif weight[k].text == '1 g':
            oneg.append(prices[k].text)
        elif weight[k].text == '1/8 oz':
            eighth.append(prices[k].text)
        elif weight[k].text == '1/4 oz':
            quarter.append(prices[k].text)
        elif weight[k].text == '1/2 oz':
            half.append(prices[k].text)
        elif weight[k].text == '1 oz':
            oneoz.append(prices[k].text)
        elif wordEach[k].text == 'each':
            each.append(prices[k].text)


    # Create a data frame
    # d = {'Name': products, 'Type': types, '1/2 g': half, '1 g': oneg, '1/8 oz': eighth, '1/4 oz': quarter, '1/2 oz': half, '1 oz': oneoz, 'Each': each}
    # df = pd.Series(d, index=['Name', 'Type', '1/2 g', '1 g', '1/8 oz', '1/4 oz', '1/2 oz', '1 oz', 'Each'])
    # df = pd.DataFrame(data=d)

    # Create series and concat
    s1 = pd.Series(products, name='Name')
    s2 = pd.Series(types, name='Type')
    s3 = pd.Series(half, name='1/2 g')
    s4 = pd.Series(oneg, name='1g')
    s5 = pd.Series(eighth, name='1/8 oz')
    s6 = pd.Series(quarter, name='1/4 oz')
    s7 = pd.Series(half, name='1/2 oz')
    s8 = pd.Series(oneoz, name='1 oz')
    s9 = pd.Series(each, name='Each')
    df = pd.concat([s1, s2, s3, s4, s5, s6, s7, s8, s9], axis=1)

    # Any cells that are empty fill them with NAN
    # np.where(pd.isnull(df))

    # Wait 3 seconds after webscraping each page
    time.sleep(3)

# When done close the driver
# driver.close()

#Save to the following location
df.to_csv(r'C:\Users\jo\oside_callW.csv', index=False, header=True, encoding='utf-8-sig')
print(df)

1 Ответ

0 голосов
/ 03 августа 2020

Я смог решить свой вопрос. Я использовал исчерпывающие списки, чтобы уменьшить размер кода. Используя следующий оператор if if weight[k].text == 'some weight'else '0' в полном списке.

import time
from selenium import webdriver
import pandas as pd

# Open the google chrome browser and navigate to website
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(executable_path=PATH)

# Total amount of pages to web scrape
MAX_PAGE_NUM = 4

# An empty list that will be used to append data frames
dflist = list()

# Iterate through the pages and web scrape
for i in range(1, MAX_PAGE_NUM + 1):
    url = "https://weedmaps.com/deliveries/callweed-2?page=" + str(i)
    driver.get(url)
    print(url)

    # Find the elements by using xpath
    product_name = driver.find_elements_by_xpath('//div[@class ="styled-components__Name-sc-186ferk-9 lbdlVL"]')
    product_type = driver.find_elements_by_xpath('//span[@class ="styled-components__BrandCategory-sc-186ferk-6 dTklNg"]')
    prices = driver.find_elements_by_xpath('//span[@class="styled-components__Price-sc-6ubro-3 dEwZFC"]')
    weight = driver.find_elements_by_xpath('//div[@class="src__Box-sc-1sbtrzs-0 src__Flex-sc-1sbtrzs-1 styled-components__UnitLabel-sc-6ubro-1 dGTmZk"]')
    wordEach = driver.find_elements_by_xpath('//div[@class="src__Box-sc-1sbtrzs-0 src__Flex-sc-1sbtrzs-1 styled-components__UnitLabel-sc-6ubro-1 dGTmZk"]')

    # Get the length of the products
    num_page_items = len(product_name)
    num_prices = len(prices)

    # Store the product names and the types in respective lists
    products = [product_name[j].text for j in range(num_page_items)]
    types = [product_type[j].text for j in range(num_page_items)]

    # Append prices to respective lists
    halfg = [prices[k].text if weight[k].text == '1/2 g'else '0' for k in range(num_page_items)]
    oneg = [prices[k].text if weight[k].text == '1 g'else '0' for k in range(num_page_items)]
    eighth = [prices[k].text if weight[k].text == '1/8 oz'else '0' for k in range(num_page_items)]
    quarter = [prices[k].text if weight[k].text == '1/4 oz'else '0' for k in range(num_page_items)]
    halfoz = [prices[k].text if weight[k].text == '1/2 oz'else '0' for k in range(num_page_items)]
    oneoz = [prices[k].text if weight[k].text == '1 oz'else '0' for k in range(num_page_items)]
    each = [prices[k].text if weight[k].text == 'each' else '0' for k in range(num_page_items)]

    # Create a data frame
    d = {'Name': products, 'Type': types, '1/2 g': halfg, '1 g': oneg, '1/8 oz': eighth, '1/4 oz': quarter,'1/2 oz': halfoz, '1 oz': oneoz, 'Each': each}
    df = pd.DataFrame(data=d)

    # Append the data frame after each iteration
    dflist.append(df)

    # Wait 3 seconds after web scraping each page
    time.sleep(3)

# When done close the driver
# driver.close()

# Concatenate all of the data frame
df = pd.concat(dflist)

#Save to the following location
df.to_csv(r'C:\Users\jo\oside_callW.csv.csv', index=False, header=True, encoding='utf-8-sig')
print(df)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...