Форум сайта python.su
Добрый день, уважаемые знатоки Python!
Возникла такая проблема, очень прошу помощи в поиске ее решения.
Есть скрипт, который парсит данный с сайта LinkedIn по конкретным фильтрам и запросам. Сам скрипт работает без вопросов, данные берутся корректно, кроме одного пункта (весь скрипт в аттачах).
Дело в том, что поле Specialties в коде содержит данные в таком виде: “specialties”: (квадратная скобка) “PCB”,“Pil”,“Led & Adaptör”,“Aluminium PCB” (квадратная скобка) . Все другие переменные имеют описание только в одних кавычках, посему содержание берется без проблем, а тут - только первое слово и хоть ты тресни…
Подскажите пожалуйста, как “научить” скрипт смотреть на открывающую и закрывающую скобку и брать данные, которые внутри них, а не только то, что в кавычках?
Часть кода прставлена ниже:
def extract_data(www,link): soup = BeautifulSoup(www) name = soup.find('h1',{'class':'name'}).text.strip() # off_name = try: size = soup.find('li',{'class':'company-size'}).find('p').text.strip() except: size = '' try: country = soup.find('li',{'class':'vcard hq'}).find('span',{'class':'country-name'}).text.strip() except: country = '' try: address = soup.find('li',{'class':'vcard hq'}).find('span',{'class':'street-address'}).text.strip() except: address = '' try: c1 = soup.find('li',{'class':'vcard hq'}).find('span',{'class':'locality'}).text.strip().replace(',','') except: c1 = '' try: c2 = soup.find('li',{'class':'vcard hq'}).find('abbr',{'class':'region'}).text.strip() except: try: c2 = soup.find('li',{'class':'vcard hq'}).find('span',{'class':'region'}).text.strip() except: c2 = '' try: specialities = soup.find('li',{'class':'specialties'}).find('p').text.strip() except: specialties = '' try: industry = soup.find('li',{'class':'industry'}).find('p').text.strip() except: industry = '' try: web = soup.find('li',{'class':'website'}).find('a').text.strip() except: web = '' try: zip_code = soup.find('li',{'class':'vcard hq'}).find('span',{'class':'postal-code'}).text.strip() except: zip_code = '' try: desc = soup.find('div',{'class':'basic-info-description'}).text.strip() except: desc = '' # print([link, name, size, country, address, c1, c2, specialties, industry, web, zip_code, desc]) return [link, name, size, country, address, c1, c2, specialties, industry, web, zip_code, desc]
Отредактировано S_K_Y_E (Ноя. 17, 2016 11:30:09)
Прикреплённый файлы: linkedin scrap.zip (6,2 KБ)
Офлайн
Самого то не задрало эту елку писать?
Если у вы видите миллион одинаковых строк кода и у вас не чешется спина - срочно меняйте профессию
def find(tag, attrs, tag1, attrs1): try: return soup.find(tag, attrs).find(tag1, attrs1).text.strip() except: return ""
c2 = find('li',{'class':'vcard hq'}, 'span',{'class':'region'}) zip_code = find('li',{'class':'vcard hq'}, 'span',{'class':'postal-code'}) # и так далее
Отредактировано FishHook (Ноя. 17, 2016 12:02:07)
Офлайн
Задрало, и еще как
Скрипт по сути достался “в наследство” и выглядел еще хуже, поверьте.. А шеф категорически не хочет слышать о смене скрипта (разве что втихую это сделаю). Посему поставлена задача типа “работайте на этом говне”.
Но а если по сути - то Ваш способ действительно выдернет все данные до следующего тэга в коде страницы?
Я просто думал, чтобы ему поставить какое-то условие конкрентно на этот тэг типа если начало идет с “открывающая скобка” то начинай копировать все вплоть до нахождения “закрывающая скобка”.
Отредактировано S_K_Y_E (Ноя. 17, 2016 12:40:35)
Офлайн
Добрый день! Прошу помощи, потому что у самого уже видимо замылен глаз и не вижу ошибку..
Есть кусок кода
with open("scraped.pkl","wb") as p: pickle.dump(out, p) out2 = [] for k in out: out2.append(k.split('?')[0]) out3 = list(set(out2)) with open('companies.txt','w',encoding='utf-8') as f: f.write('\n'.join(out3)) except Exception as ex: print(ex) print(traceback.format_exc()) with open("err result.pkl","wb") as p: pickle.dump(out, p) print('error dump OK') input() finally: driver.quit()
Офлайн
S_K_Y_EВо второй строке перед pickle лишний отступ. Он определяет блок для with, и всё, что ниже, не принадлежит этому блоку, потому что отступ другой. А когда он доходит до следующей строки, с out2, он видит отступ в строке и не понимает, чей это отступ (отступ блока какой конструкции) и выдаёт синтаксическую ошибку. А синтаксические ошибки исключениями не считаются.
даже не создает + практически моментально закрывает окно
S_K_Y_EТебе надо научиться запускать программы в консоли (для этого открывать консоль отдельно). Тогда бы ты увидел, что там пишется.
практически моментально закрывает окно
Отредактировано py.user.next (Ноя. 21, 2016 04:32:32)
Офлайн
Спасибо большое за ответ!
Попробую изменить синтаксическую конструкцию и попробую еще раз
Про консоль вообще вылетело из головы, но потом додумался, и вот что выдает:
Т.е. это и есть синтаксическая ошибка?
Офлайн
S_K_Y_EЭто уже другая ошибка. k - это не строка, а список.
Т.е. это и есть синтаксическая ошибка?
Офлайн
py.user.next спасибо за ответ!
Тогда это немного странно, т.к. я формирую файл как единую строку, чтобы в дальнейшем ее как раз и разбить на отдельные строки по сепаратору..
Код такой:
from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import Select from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import NoAlertPresentException import unittest, time, re import traceback import os import pickle import csv from bs4 import BeautifulSoup import pprint import random from account import settings links = [i.strip() for i in open('links.txt')] random.shuffle(links) try: if 1: driver = webdriver.Chrome() driver.set_window_size(1200, 800) driver.implicitly_wait(4) else: profile=webdriver.FirefoxProfile() profile.set_preference("intl.accept_languages", "en") firefox_capabilities = DesiredCapabilities.FIREFOX firefox_capabilities['marionette'] = True driver = webdriver.Firefox(firefox_profile=profile,capabilities=firefox_capabilities) driver.set_window_size(1300, 1000) driver.implicitly_wait(30) driver.get("http://www.linkedin.com") time.sleep(3) emailBox = driver.find_element_by_xpath("//input[@id='login-email']") emailBox.send_keys(settings['login']) time.sleep(2) passwordBox = driver.find_element_by_xpath("//input[@id='login-password']") passwordBox.send_keys(settings['pass']) time.sleep(2) passwordBox.submit() time.sleep(5) out = [] cntr = 1 for link in links: print('Link %s/%s' % (cntr, len(links))) cntr += 1 buf = [] driver.get(link) time.sleep(3) pcnt = 1 while True: pag = driver.find_elements_by_xpath("//div[@id='results-pagination']/ul[@class='pagination']/li[@class='next']") print("Page: %s" % pcnt) pcnt += 1 if len(pag) > 0: print('next page button') urls = driver.find_elements_by_xpath("//div[@id='results-container']/ol[@id='results']/li/div[@class='bd']/h3/a") if urls: hrefs = [i.get_attribute('href') for i in urls] buf += hrefs driver.find_element_by_xpath("//div[@id='results-pagination']/ul[@class='pagination']/li[@class='next']").click() else: print('no next page button') urls = driver.find_elements_by_xpath("//div[@id='results-container']/ol[@id='results']/li/div[@class='bd']/h3/a") if urls: hrefs = [i.get_attribute('href') for i in urls] buf += hrefs break time.sleep(3) out.append([link, buf]) time.sleep(3) with open("scraped.pkl","wb") as p: pickle.dump(out, p) out2 = [] for k in out: out2.append(k.split('?')[0]) out3 = list(set(out2)) with open('companies.txt','w',encoding='utf-8') as f: f.write('\n'.join(out3)) except Exception as ex: print(ex) print(traceback.format_exc()) with open("err result.pkl","wb") as p: pickle.dump(out, p) print('error dump OK') input() finally: driver.quit()
Офлайн
S_K_Y_EНу, вот у тебя список добавляется в out. У тебя получается, что out - это список списков, где каждый список в out представляет из себя строку link и список строк buf. При переборе надо просто смотреть на элементы out как на списки, а не как на строки. А чтобы получить строки, нужно дальше раскладывать.out.append([link, buf])
S_K_Y_EНу, это же формат pickle, там пишется служебная информация о каждом сохранённом объекте, чтобы потом его можно было точно восстановить. Список - это объект, строка - это объект, число - это объект. Объект обладает типом. При сохранении записывается всё об объектах и их вложенности.
Что меня сильно начало смущать - так это то, что данные после работы скрипта в файле показываются ну в очень странный способ:
Отредактировано py.user.next (Ноя. 22, 2016 02:59:40)
Офлайн