Advertisement
Guest User

2104

a guest
Apr 21st, 2015
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.27 KB | None | 0 0
  1. from grab import Grab
  2. import os.path
  3. import xlwt
  4. import xlsxwriter
  5. import webbrowser
  6. #from xlutils.copy import copy
  7.  
  8. BASE_URL = "http://www.svetlux.ru/"
  9. CAT_FILE = "categories.xls"
  10. SUBCAT_FILE = "subcategories.xls"
  11. SERIES_FILE = "series.txt"
  12. #SERIES_FILE = "cat2/myfile.txt"
  13. ITEMS_FILE = "items.xls"
  14.  
  15. ATTRIBS_NAMES_FILE = "attribs.txt"
  16.  
  17. CAT_HEADER = ['name','cat_id','parent_id']
  18. SUBCAT_HEADER = ['name','cat_id','parent_id']
  19. SERIES_HEADER = ['name','cat_id','parent_id','img_url']
  20. ITEMS_HEADER = ["product_id", "name(en)", "name(ru)", "categories", "sku", "upc", "ean", "jan", "isbn", "mpn", "location", "quantity", "model", "manufacturer", "image_name", "shipping", "price", "points", "date_added", "date_modified", "date_available", "weight", "weight_unit", "length", "width", "height", "length_unit", "status", "tax_class_id", "seo_keyword", "description(en)", "description(ru)", "meta_title(en)", "meta_title(ru)", "meta_description(en)", "meta_description(ru)", "meta_keywords(en)", "meta_keywords(ru)", "stock_status_id", "store_ids", "layout", "related_ids", "tags(en)", "tags(ru)", "sort_order", "subtract", "minimum"]
  21.  
  22. FIRST_ITEM_NUMBER = 5616 # ID первого товара
  23.  
  24. document_charset='Windows-1251'
  25.  
  26. categories = {}
  27. subcategories = {}
  28. series={}
  29. series_parsed = 0
  30. item_attrs_names=[]
  31. items = [] # пачка готовых строк, по одной строке на товар серии
  32. myset = []
  33. items_count = 0 # количеcтво спарсенных, нужно для нумерации
  34.  
  35. serie_id = 1667
  36.  
  37. def check_url(url):
  38.  
  39.         result_url = url
  40.         if not url.startswith('/') and not BASE_URL.endswith('/'):
  41.                 url = '/' + url
  42.         if BASE_URL not in url:
  43.                 result_url = BASE_URL + url
  44.         if not url.endswith('/') and not url.endswith('.jpg'):
  45.                 result_url += '/'
  46.         return result_url
  47.  
  48. def get_categories():     #TESTED : OK
  49.         g = Grab()
  50.         g.go(url = BASE_URL,document_charset=document_charset)
  51.         found = g.doc.select('//*[@class="category"]/a')
  52.         cat_id = 1
  53.         parent_id = 0
  54.         if found.exists:
  55.             for elem in found:
  56.                 raw = str(elem.html())
  57.                 url = raw[10:raw.index('style') - 2 ]
  58.                 categories[url] = elem.text(), cat_id, parent_id
  59.                 cat_id += 1
  60.  
  61. def get_subcategories(cat_url,next_cat_num):
  62.         cat_id = next_cat_num
  63.  
  64.         g = Grab()      
  65.         g.go(url = BASE_URL + cat_url,document_charset=document_charset)
  66.         found = g.doc.select('//*[@class="subcat"]/a')
  67.         print(categories[cat_url])
  68.         for elem in found:
  69.             parent_id = categories[cat_url][0]
  70.             print(parent_id)
  71.             raw = str(elem.html())
  72.             url = raw[10:raw.index('style') - 2 ]
  73.             subcategories[url] = elem.text(),cat_id,parent_id, url
  74.             #print(subcategories[url])
  75.             cat_id+=1
  76.  
  77. def get_series(url): #get all series of category
  78.     url = check_url(url)
  79.     g = Grab()
  80.     g.go(url = url, document_charset=document_charset)
  81.     found = g.doc.select('//*[@class="saleitem"]') # [@class="saleitem"]/div[1]
  82.     if found.exists:
  83.             for ser in found:
  84.                 k = ser.select('./div[*]/div[@class="zagolovok"]')
  85.                 img = ser.select('//*[@class="img lazy"]')
  86.                 for elem in k:
  87.                     try:
  88.                         value = elem.html()[32: (elem.html().index('/">') ) ]
  89.                         key = elem.text()
  90.                         if url in series.keys() and value not in series[url]:
  91.                             series[url].append([value,key])
  92.                         else:
  93.                             series[url] = [[value,key],]
  94.                             #print(elem.text())  # parse clean text
  95.                     except:
  96.                             ValueError
  97.        
  98. def get_urls(raw, dest): #
  99.         for elem in raw:
  100.             dest.append( str(elem [9:elem.index('style') - 3 ]))
  101.  
  102. def series_txt_item_parse():  #  возвращает по одному урл из SERIES_FILE
  103.     lines = open(SERIES_FILE).read().splitlines()
  104.     try:
  105.         x = serie_id
  106.         while True:
  107.             print(lines[x])
  108.             a=lines[x].split('|')
  109.             serie_url = a[3]
  110.             ser_id = a[2]+','+a[1]+','+a[0]
  111.             get_items(serie_url,ser_id)  #  отдаем на спарс урл и id
  112.             x += 1
  113.     except FileNotFoundError:
  114.         print('File not exists')
  115.  
  116.  
  117. def get_items(url,ser_id):  # парсит все товары серии по url серии
  118.     global items_count
  119.     url = check_url(url)
  120.     g = Grab()
  121.     g.go(url = url, document_charset=document_charset)
  122.     found = g.doc.select('//*[@class="fleft name2p"]')
  123.     if found.exists:
  124.         print('\n' + url + '  serie completed     OK' + '\n')
  125.         for ser in found:
  126.             item_attrs = {}
  127.             item_url = ser.html()            
  128.             item_title = ser.text()
  129.             item_url = item_url[item_url.index('><a href="')+11:item_url.index('"><div') ]
  130.             img_url = ser.html()
  131.             img_url = img_url[img_url.index(": url('/")+8:img_url.index("') no-") ]
  132.             item_attrs['product_id'] = FIRST_ITEM_NUMBER + items_count
  133.             items_count += 1           
  134.             item_attrs['item_name'] = item_title
  135.             item_attrs['item_url'] = item_url  
  136.             item_attrs['item.series'] = ser_id  #  TODO имя серии!!!!!!!!!! пока cтавит   урл серии вместо имени
  137.             item_attrs['image_name'] = img_url  
  138.             item_attrs['price'] = get_price(item_url)    
  139.             print(item_url)
  140.             item_attrs['description'] = get_item_table(BASE_URL + item_attrs['item_url'])
  141.             attrs_to_row(item_attrs)
  142.         print('\n' + url + '  serie completed     OK' )
  143. #вместо имени серии берем первые цифры урла до _
  144.         serie_name = url[url.index('catalog/')+8:url.index('_')]
  145.  
  146.         export_items(serie_name)        #серия спарсена, можно экспортить
  147.         print('\n' + url + '  serie  saved   to ' + serie_name + '.xls      \n')
  148.        
  149.      
  150.  
  151. def get_item_table(item_url): #  характеристики для description
  152.     item_url = check_url(item_url)
  153.     g = Grab()
  154.     g.go(url = item_url, document_charset=document_charset)
  155.     found = g.doc.select('//*[@id="main"]/div[1]/div[2]/div[1]/table')
  156.     if found.exists:
  157.         result = []
  158.         text = found.html()                    
  159.         new_text = []
  160.         for x in ['</table>','<table>','<b>','</b>','\n','<tr>']:
  161.             text = text.replace(x,'')
  162.             text = text.replace('</tr>','   ')
  163.  
  164.         text = text.split('   ')
  165.         for a in text:
  166.             new_text.append(a.replace('</td><td>','    '))
  167.         for a in new_text:
  168.             a = a.replace('<td>','')
  169.             a = a.replace('</td>','')
  170.             result.append(a)      
  171.         item_buffer={}  # list  [ключ, значение, ключ, значение ...]
  172.         for i in result:
  173.             if not i.partition('    ')[0] == '':
  174.                 item_buffer[i.partition('    ')[0]] = i.partition('    ')[2]
  175.         #print(item_buffer)
  176.         return item_buffer
  177.  
  178.  
  179. def attrs_to_row(item_attrs): # формируем строку из параметров таблицы, чтобюы потом экспортнуть её
  180.    
  181.  
  182.  
  183.     item_row = []
  184.     item_attrs_names=[]
  185.  
  186.     #          ЗНАЧЕНИЯ                        #  СТОЛБЦЫ
  187.     item_row.append(item_attrs['product_id'])  #  "product_id  - для первого товара это FIRST_ITEM_NUMBER
  188.     item_row.append("")                        #  " name(en)
  189.     item_row.append(item_attrs['item_name'])   #  "name(ru)"
  190.     item_row.append(item_attrs['item.series'])  #  "categories",   имя серии!!!!!!!!!! пока cтавит   урл серии вместо имени
  191.     if 'Артикул' in item_attrs['description'].keys():
  192.         item_row.append(item_attrs['description']['Артикул'])                        #  "sku",   -  выбрать sku
  193.     else:
  194.         item_row.append("")
  195.     item_row.append("")                        #  "upc"
  196.     item_row.append("")                        #  "ean",
  197.     item_row.append("")                        #  "jan"
  198.     item_row.append("")                        #  "isbn"
  199.     item_row.append("")                        #  "mpn"
  200.     item_row.append("")                        #  "location"    
  201.     item_row.append("999")                     #"quantity",
  202.     item_row.append(item_row[4])                 # "model",
  203.  
  204.     if 'Производитель' in item_attrs['description'].keys():
  205.         item_row.append(item_attrs['description']['Производитель'])                    
  206.     else:
  207.         item_row.append("")              # "manufacturer"
  208.  
  209.    
  210.     item_row.append(item_attrs['image_name'].replace('images/pics','catalog')) # image_name
  211.     item_row.append("yes"  )                   #  "shipping",
  212.     item_row.append(item_attrs['price'].replace(' ',''))                #  "price",
  213.     item_row.append("0")                       #      "points", "date_added",
  214.     item_row.append("2015-01-01 00:00:00")
  215.     item_row.append("2015-01-01 00:00:00" )     #  date_modified",
  216.     item_row.append("2015-01-01 00:00:00")      # "date_available"
  217.     item_row.append(0)                          # "weight"
  218.     item_row.append('kg')                        # "weight_unit",
  219.     item_row.append(0)                          # "length"
  220.     item_row.append(0)                         # "width",
  221.     item_row.append(0)                         # "height"
  222.     item_row.append("cm")                      #  "length_unit"
  223.     item_row.append("true")                    #  "status",
  224.     item_row.append("0")                       # "tax_class_id",
  225.     item_row.append("")                        # "seo_keyword",
  226.     item_row.append("")                        # "description(en)"
  227.     item_row.append(item_attrs['description']) #  "description(ru)"   номер [-16]
  228.     item_row.append("")                        #  "meta_title(en)",
  229.     item_row.append(item_attrs['item_name'])   #  "meta_title(ru)",
  230.     item_row.append("")                        #  "meta_description(en)",
  231.     item_row.append("")                        #  "meta_description(ru)",
  232.     item_row.append("")                        #  "meta_keywords(en)",
  233.     item_row.append("")                        #  "meta_keywords(ru)",
  234.     item_row.append("6")                       #  "stock_status_id",
  235.     item_row.append("0")                       #  "store_ids",
  236.     item_row.append("")                        #  "layout",
  237.     item_row.append("")                        #  "related_ids",
  238.     item_row.append("")                        #  "tags(en)",
  239.     item_row.append("")                        #  "tags(ru)",
  240.     item_row.append("1")                       #  "sort_order"
  241.     item_row.append("true")                    #  "subtract"  
  242.     item_row.append("1")                       #  "minimum"
  243.    
  244.     for attr_name in item_attrs['description'].keys():
  245.         if attr_name not in myset:  # ВСЕ названия аттрибутов товара   - после экспорта в таблицу затирается из нее
  246.             myset.append(attr_name)
  247.    
  248.     items.append(item_row)
  249.     #print(item_row)
  250.  
  251. def get_price(url):
  252.     check_url(url)
  253.     url = check_url(url)
  254.     g = Grab()
  255.     g.go(url = url, document_charset=document_charset)
  256.     found = g.doc.select('/html/body/div[6]/div/div[6]/div[3]/div[1]/div[2]/div[2]/div[2]/div/div[1]/span[1] ')
  257.     for k in found:
  258.         price = k.text()
  259.     return price
  260.  
  261.  
  262. def export(level,sheet_name,row): #  export to txt   (level = ['cat', 'subcat' ,'series' , 'items'] )
  263.     if level == 'cat':
  264.         source = categories
  265.         dest_file = CAT_FILE
  266.         header = CAT_HEADER
  267.  
  268.     elif level == 'subcat':
  269.         source = subcategories
  270.         dest_file = SUBCAT_FILE
  271.         header = SUBCAT_HEADER
  272.  
  273.     elif level == 'series':
  274.         source = series
  275.         dest_file = SERIES_FILE
  276.         header = SERIES_HEADER
  277.  
  278.     elif level == 'items':                     # используй export_items()
  279.         export_items(serie_name)               # вызов export_items()
  280.  
  281.     else:
  282.         raise NameError
  283.  
  284.     wb = xlwt.Workbook(encoding = 'utf-8')
  285.     ws = wb.add_sheet(sheet_name)
  286.     col = 0
  287.     if not os.path.isfile(dest_file): # если файл уже есть, то
  288.         for attr in header:           # заполняем таблицу
  289.             ws.write(0,col,attr)
  290.             col +=1      
  291.         row = 1
  292.     else:        
  293.         print('File is exist')
  294.         fill_table(source, dest_file, wb, ws, row, level)
  295.  
  296.  
  297. def fill_table(source, dest_file, wb, ws, row, level ):
  298.  
  299.     for elem in items:
  300.         #print(elem)
  301.         fill_items_table(wb, ws, row, item_row )
  302.         col=0
  303.         for attr in elem[1]:
  304.             ws.write(row,col,str(attr))
  305.             col +=1
  306.         row+= 1
  307.         wb.save(dest_file)
  308.  
  309.  
  310. def export_items(serie_name):
  311.     global serie_id
  312.     dest_file = str('sr/' + str(serie_id) + '.xls')
  313.     serie_id +=1
  314.     header = ITEMS_HEADER
  315.  
  316.     wb = xlsxwriter.Workbook(dest_file)
  317.     ws = wb.add_worksheet('Products')
  318.     col = 0
  319.     #if not os.path.isfile(dest_file): # если файла нет, то
  320.     for attr in header:           # заполняем заголовок
  321.         ws.write(0,col,attr)
  322.         col +=1
  323.     print(dest_file + '  is created. Header added')
  324.     row = 1
  325.      
  326.  
  327.     while len(items):
  328.         #print(items)
  329.         col = 0
  330.         for elem in items.pop(len(items) -1):
  331.             print(elem)
  332.             ws.write(row,col,str(elem))
  333.             col+= 1
  334.         row+= 1
  335.  
  336.     ws = wb.add_worksheet('ProductAttributes')
  337.     ws.write(0,0,'attribute_group')
  338.     ws.write(0,1,'ProductAttributes')
  339.     ws.write(1,0,'1')
  340.     print(item_attrs_names)
  341.     ws.write(1,1, str(myset[1:-1]))
  342.    
  343.     wb.close()    
  344.  
  345.     # и пишем список аттрибутов в общий файл
  346.  
  347.     print(dest_file + ' is saved' )
  348.  
  349.  
  350. if __name__ == '__main__':
  351.   series_txt_item_parse()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement