Вопрос по парсингу на Python + BeautifulSoup
import csv
import requests
from bs4 import BeautifulSoup
def get_html(url):
try:
r = requests.get(url)
return r.text
except Exception as ex:
print('Ошибка в функции get_html()', ex)
def write_csv(data):
with open('chip_dip_last.csv', 'a', encoding='utf-8') as f:
writer = csv.writer(f, delimiter='@')
writer.writerow((data['name'],
data['path'],
data['price'],
data['descriptions'],
data['documentation_href'],
data['documentation_description'],
data['item_number'],
data['artikul'],
data['part_number'],
data['brand'],
data['video'],
data['full_jpeg'],
data['small_jpeg'],
data['url']))
def get_data(url, path, product_name, product_avtor):
html = get_html(url)
soup = BeautifulSoup(html, 'lxml')
try:
price = soup.find('span', class_='ordering__value').text.strip()
except:
price = ''
try:
descriptions = soup.find('div', class_='showhide item_desc').text.strip()
descriptions = descriptions.replace('\n', '')
except:
descriptions = ''
try:
hrefs = soup.find('div', class_='product__documentation ptext').find_all('div', class_='download download_zip')
if len(hrefs) > 1:
documentation_href = ''
for href in hrefs:
url = href.find('a', class_='link download__link').get('href')
urls = f'{url}; '
documentation_href += urls
else:
documentation_href = hrefs[0].find('a', class_='link download__link').get('href')
except:
documentation_href = ''
try:
descriptions_doc = soup.find('div', class_='product__documentation ptext').find_all('div',
class_='download download_zip')
if len(descriptions_doc) > 1:
documentation_description = ''
for description in descriptions_doc:
text = description.find('a', class_='link download__link').text.strip()
texts = f'{text}; '
documentation_description += texts
else:
documentation_description = descriptions_doc[0].find('a', class_='link download__link').text.strip()
except:
documentation_description = ''
try:
item_numbers = soup.find('div', class_='product_main-ids ptext').find_all('div', class_='product_main-id')
item_number = item_numbers[0].find_all('span')[-1].text.strip()
except:
item_number = ''
try:
artikuls = soup.find('div', class_='product_main-ids ptext').find_all('div', class_='product_main-id')
artikul = artikuls[1].find('span', itemprop='model').text.strip()
except:
artikul = ''
try:
part_numbers = soup.find_all('div', class_='product_main-id')
part_number = part_numbers[2].find('span', itemprop='mpn').text
except:
part_number = ''
try:
videos = soup.find_all('div', class_='video')
if len(videos) > 1:
video = ''
for item in videos:
url = 'https://www.chipdip.ru' + item.find('a').get('href')
urls = f'{url}; '
video += urls
else:
video = 'https://www.chipdip.ru' + videos[0].find('a').get('href')
except:
video = ''
try:
full_jpeg = soup.find_all('span', class_='galery')[0].find('img').get('src')
except:
full_jpeg = ''
try:
small_jpeg = soup.find_all('span', class_='galery')[1].find('img').get('src')
except:
small_jpeg = ''
data = {'name': product_name,
'path': path,
'price': price,
'descriptions': descriptions,
'documentation_href': documentation_href,
'documentation_description': documentation_description,
'item_number': item_number,
'artikul': artikul,
'part_number': part_number,
'brand': product_avtor,
'video': video,
'full_jpeg': full_jpeg,
'small_jpeg': small_jpeg,
'url': url}
write_csv(data)
def get_block_url(block_name, catalog_header, item_url):
for page in range(1, 1001):
url = item_url + f'?page={page}'
html = get_html(url)
soup = BeautifulSoup(html, 'lxml')
blocks = soup.find_all('div', class_='item')
if len(blocks) > 0:
for block in blocks:
product_url = 'https://www.chipdip.ru' + block.find('div', class_='item__name').find('a').get('href')
product_avtor = block.find('div', class_='item__mnf font-m').text.strip()
product_path = f'{block_name}/{catalog_header}/{product_avtor}'
product_name = block.find('div', class_='item__name').find('a').text.strip()
get_data(product_url, product_path, product_name, product_avtor)
else:
break
def get_categories_urls(block_name, url):
html = get_html(url)
soup = BeautifulSoup(html, 'lxml')
items = soup.find_all('div', class_='catalog__g1 clear')
for item in items:
catalog_header = item.find('div', class_='catalog__header').find('a',
class_='link link_dark like-header like-header_3').text.strip()
block_url = 'https://www.chipdip.ru' + item.find('a').get('href')
get_block_url(block_name, catalog_header, block_url)
def get_content(html):
soup = BeautifulSoup(html, 'lxml')
block_url = 'https://www.chipdip.ru' + soup.find('ul', class_='cat-menu').find_all('li')[-1].find('a').get('href')
block_name = soup.find('ul', class_='cat-menu').find_all('li')[-1].find('a').text
get_categories_urls(block_name, block_url)
def main():
url = 'https://www.chipdip.ru'
get_content(get_html(url))
if __name__ == '__main__':
main()
Парсер собирает данные с последнего раздела на сайте. Все данные вроде бы собирает,записывает в .csv формат. Затем я захожу в excel в диологовом окне выбираю данные/получение внешних данных/из текста. Выбираю свой файл,открывается окно редактирования,там выбираю кадировку, и вот самое главное, я выбираю разделитель, и выбираю символ @, так как указал его в коде(функция write_csv()). Все данные укладываются в колонки, но есть проблема, укладываются криво.Почему то именно description(описание), оно залезает в первую колонку,короче не на своем месте становится.Не везде так, но во многих строках. Может из за того, что слишком много текста в этой строке,или я не понимаю... Помогите пожалуйста,может в коде нужно что то поправить.
