Неправильный формат (неправильное количество столбцов) после записи в файлы csv

Мое намерение состоит в том, чтобы получить полный обзор всех профилей вместе с заголовком обзора, именем пользователя, местоположением пользователя и временем публикации на веб-страницах веб-сайта Reliance Jio Reviews и сохранить его в файле CSV.

Я хочу сканировать веб-сайт http://www.mouthshut.com/mobile-operators/Reliance-Jio-reviews-925812061

Когда я попытался сохранить очищенные данные первых двух страниц в файле CSV, я получил следующий результат. Моя проблема заключается в том, что вывод в каждой строке генерирует больше столбцов, чем нужно. Одно предложение разбивается на множество ячеек.

Скриншот CSV-файла, содержащего очищенные данные

Мой код:

from bs4 import BeautifulSoup
from urllib.request import urlopen as uReq
from selenium import webdriver;import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import csv

firefox_capabilities = DesiredCapabilities.FIREFOX
firefox_capabilities['marionette'] = True
firefox_capabilities['binary'] = '/etc/firefox'

driver = webdriver.Firefox(capabilities=firefox_capabilities)
url = "http://www.mouthshut.com/mobile-operators/Reliance-Jio-reviews-925812061"
driver.get(url)
wait = WebDriverWait(driver, 10)
soup=BeautifulSoup(driver.page_source,"lxml")
for items1 in    wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".review-article"))):
   link1 = items1.find_element_by_css_selector(".reviewdata a")
   link1.click()
   time.sleep(2)
csv = open('index.csv','w')
column = "Name,Location,Review_data,Review_title,Review_data\n"
csv.write(column)
soup1 = BeautifulSoup(driver.page_source,"lxml")
for item1 in soup1.select(".review-article"):
   name1 = item1.select("p a")[0].text
   location1 = item1.select("p")[1].text
   review_date1 = item1.select("small")[0].text
   review_title1 = item1.select("strong  a[id^=ctl00_ctl00_ContentPlaceHolderFooter_ContentPlaceHolderBody_rptreviews]")[0].text
   review_data1 = ' '.join([' '.join(items1.text.split()) for items1 in   item1.select(".reviewdata")])
   print("Name: {}\nLocation : {}\nReview_date: {}\nReview_Title: {}\nReview_Data: {}\n".format(name1, location1, review_date1, review_title1, review_data1))
   csv1 = open('index.csv','a')
   page1_data = name1 + "," + location1 + "," + review_date1 + "," + review_title1  + "," + review_data1  + "\n" 
   csv1.write(page1_data)
uclient=uReq(url)
page_html=uclient.read()
uclient.close()
page_soup = soup(page_html,"html.parser")
container = soup.find("ul",{"class":"pages table"})
all_li = container.findAll("li")
last_div = None
for last_div in all_li:pass
if last_div:
   content = last_div.getText()
   content1 = int(content)
   container1 = soup.findAll("li",{"class":"next"})
   li=container1[0].find("a",{"class":"btn btn-link"}).attrs['href']    
driver.get(li)
wait = WebDriverWait(driver, 10)
soup=BeautifulSoup(driver.page_source,"lxml")
for items in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".review-article"))):
   link = items.find_element_by_css_selector(".reviewdata a")
   link.click()
   time.sleep(2)

soup = BeautifulSoup(driver.page_source,"lxml")
for item in soup.select(".review-article"):
    name = item.select("p a")[0].text
    location = item.select("p")[1].text
    review_date = item.select("small")[0].text
    review_title = item.select("strong a[id^=ctl00_ctl00_ContentPlaceHolderFooter_ContentPlaceHolderBody_rptreviews]")[0].text
    review_data = ' '.join([' '.join(items.text.split()) for items in item.select(".reviewdata")])
    print("Name: {}\nLocation : {}\nReview_date: {}\nReview_Title: {}\nReview_Data: {}\n".format(name, location, review_date, review_title, review_data))
    csv2 = open("index.csv",'a')
    page2_data = name  +","+ location+"," + review_date +","+ review_title +","+ review_data + "\n"
    csv2.write(page2_data)
    driver.quit()

Мне нужна помощь, чтобы выяснить ошибку в моем коде для хранения очищенных данных в файле CSV в структурированном виде.


person Monisha    schedule 21.12.2017    source источник
comment
лучше использовать модуль csv для сохранения данных - кажется, у вас есть запятая в каком-то тексте, и теперь он обрабатывает этот текст как несколько столбцов. С модулем csv у вас не будет этой проблемы, потому что он поместит текст в дополнительный " ". Это также решает проблему, когда в данных есть ввод/новая строка.   -  person furas    schedule 21.12.2017
comment
Можете ли вы помочь мне, обновив код?   -  person Monisha    schedule 22.12.2017


Ответы (3)


Видеть

page1_data = name1 + "," + location1 + "," + review_date1 + "," + review_title1  + "," + review_data1  + "\n" 
csv1.write(page1_data)

Запятая уже используется, скажем, в месте: Дели, Индия. Если вы продолжаете использовать запятую, как вы делали выше, файл csv не может быть проанализирован должным образом.

**Одним из способов обхода является пометка "" вокруг текста, содержащего запятую. Таким образом, после этого шага Дели, Индия, превратится в «\Дели, Индия». **

def preprocess(text):
    if "," in text:
        return '"' + text + '"'
    return text

Оберните каждый текст функцией.

page1_data = preprocess(name1) + "," + preprocess(location1) + "," + preprocess(review_date1) + "," + preprocess(review_title1)  + "," + preprocess(review_data1)  + "\n" 

Это должно работать.

Другим способом должно быть изменение разделителя на другие символы.

person Tai    schedule 21.12.2017
comment
Можете ли вы дать пример кода для того же? Поскольку я новичок в python, я запутался в шагах для этого. - person Monisha; 22.12.2017
comment
@Monisha Попробуйте это. - person Tai; 22.12.2017
comment
Я модифицировал функцию, чтобы объединить пробелы в тексте, и это сработало. Спасибо за вашу помощь. - person Monisha; 22.12.2017

Просмотрите файл csv в текстовом редакторе. Проблема в том, что ваша программа для работы с электронными таблицами анализирует ОБА запятые и пробелы.

Другая проблема заключается в том, что вы не учли запятые ВНУТРИ ваших очищенных данных. Именно поэтому у вас город и страна в разных ячейках. Вам нужно будет заключать в кавычки значения, внутри которых есть запятые.

person dstudeba    schedule 21.12.2017
comment
Я не знаю, как поставить двойные кавычки для имени переменной, так как имя переменной будет рассматриваться как строка, если мы поместим его в двойные кавычки. - person Monisha; 22.12.2017

Вам следует использовать модуль csv, потому что он автоматически решит проблему с запятой и "новой строкой"/вводом в тексте.

Создать модуль записи csv

f = open('index.csv','w')
csv_writer = csv.writer(f)

и писать заголовки, используя список, а не одну строку

column = ["Name", "Location", "Review_data", "Review_title", "Review_data"]
csv_writer.writerow(column)

так же написать список с данными

row = [name, location, review_date, review_title, review_data]
csv_writer.writerow(row)

Полный код

from bs4 import BeautifulSoup
from urllib.request import urlopen as uReq
from selenium import webdriver;import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import csv

# --- init ---

firefox_capabilities = DesiredCapabilities.FIREFOX
firefox_capabilities['marionette'] = True
firefox_capabilities['binary'] = '/etc/firefox'

driver = webdriver.Firefox(capabilities=firefox_capabilities)
url = "http://www.mouthshut.com/mobile-operators/Reliance-Jio-reviews-925812061"

# --- open file ---

f = open("index.csv", "w")
csv_writer = csv.writer(f)

columns = ["Name", "Location", "Review_data", "Review_title", "Review_data"]
csv_writer.writerow(columns)

# ---- get data ---

driver.get(url)
wait = WebDriverWait(driver, 10)

soup = BeautifulSoup(driver.page_source, "lxml")
for items in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".review-article"))):
   link = items.find_element_by_css_selector(".reviewdata a")
   link.click()
   time.sleep(2)

soup = BeautifulSoup(driver.page_source, "lxml")

for item in soup.select(".review-article"):
    name = item.select("p a")[0].text
    location = item.select("p")[1].text
    review_date = item.select("small")[0].text
    review_title = item.select("strong  a[id^=ctl00_ctl00_ContentPlaceHolderFooter_ContentPlaceHolderBody_rptreviews]")[0].text
    review_data = ' '.join([' '.join(items.text.split()) for items in item.select(".reviewdata")])

    print("Name:", name)
    print("Location:", location)
    print("Review_date:", review_date)
    print("Review_Title:", review_title)
    print("Review_Data:", review_data)

    row = [name, location, review_date, review_title, review_data]
    csv_writer.writerow(row)

# --- get next url ---

uclient = uReq(url)
page_html = uclient.read()
uclient.close()

soup = BeautifulSoup(page_html, "html.parser")
container = soup.find("ul", {"class": "pages table"})

all_li = container.findAll("li")
if all_li:
    last_div = all_li[-1]
    content = last_div.getText()
    content = int(content)
    container = soup.findAll("li", {"class": "next"})
    li = container[0].find("a", {"class": "btn btn-link"}).attrs['href']

# ---- get data ---

driver.get(li)
wait = WebDriverWait(driver, 10)

soup = BeautifulSoup(driver.page_source, "lxml")
for items in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".review-article"))):
    link = items.find_element_by_css_selector(".reviewdata a")
    link.click()
    time.sleep(2)

soup = BeautifulSoup(driver.page_source, "lxml")
for item in soup.select(".review-article"):
    name = item.select("p a")[0].text
    location = item.select("p")[1].text
    review_date = item.select("small")[0].text
    review_title = item.select("strong a[id^=ctl00_ctl00_ContentPlaceHolderFooter_ContentPlaceHolderBody_rptreviews]")[0].text
    review_data = ' '.join([' '.join(items.text.split()) for items in item.select(".reviewdata")])

    print("Name:", name)
    print("Location:", location)
    print("Review_date:", review_date)
    print("Review_Title:", review_title)
    print("Review_Data:", review_data)

    row = [name, location, review_date, review_title, review_data]
    csv_writer.writerow(row)

# --- end ---

driver.quit()
f.close()

EDIT: версия без beautifulsoup и requests - только selenium

from selenium import webdriver;import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import csv

def get_data(driver, csv_writer):

    for item in driver.find_elements_by_css_selector(".review-article"):
        name = item.find_elements_by_css_selector("p a")[0].text
        location = item.find_elements_by_css_selector("p")[1].text
        review_date = item.find_elements_by_css_selector("small")[0].text
        review_title = item.find_elements_by_css_selector("strong  a[id^=ctl00_ctl00_ContentPlaceHolderFooter_ContentPlaceHolderBody_rptreviews]")[0].text
        review_data = item.find_elements_by_css_selector(".reviewdata")
        review_data = ' '.join([' '.join(items.text.split()) for items in review_data])

        print("Name:", name)
        print("Location:", location)
        print("Review_date:", review_date)
        print("Review_Title:", review_title)
        print("Review_Data:", review_data)

        row = [name, location, review_date, review_title, review_data]
        csv_writer.writerow(row)

# --- init ---

firefox_capabilities = DesiredCapabilities.FIREFOX
firefox_capabilities['marionette'] = True
firefox_capabilities['binary'] = '/etc/firefox'

driver = webdriver.Firefox(capabilities=firefox_capabilities)
url = "http://www.mouthshut.com/mobile-operators/Reliance-Jio-reviews-925812061"

# --- open file ---

f = open("index.csv", "w")
csv_writer = csv.writer(f)

columns = ["Name", "Location", "Review_data", "Review_title", "Review_data"]
csv_writer.writerow(columns)

# ---- get data ---

print('url:', url)

driver.get(url)
wait = WebDriverWait(driver, 10)

get_data(driver, csv_writer)

# --- get next url ---

url = driver.find_element_by_xpath('//li[@class="next"]/a').get_attribute("href")

# ---- get data ---

print('url:', url)

driver.get(url)
wait = WebDriverWait(driver, 10)

get_data(driver, csv_writer)

# --- end ---

driver.quit()
f.close()
person furas    schedule 22.12.2017