Найти - Пользователи
Полная версия: Парсинг сайта LinkedIn
Начало » Python для новичков » Парсинг сайта LinkedIn
1
S_K_Y_E
Добрый день, уважаемые знатоки 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]

Заранее огромное спасибо!
FishHook
Самого то не задрало эту елку писать?
Если у вы видите миллион одинаковых строк кода и у вас не чешется спина - срочно меняйте профессию


  
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'})
# и так далее
S_K_Y_E
Задрало, и еще как
Скрипт по сути достался “в наследство” и выглядел еще хуже, поверьте.. А шеф категорически не хочет слышать о смене скрипта (разве что втихую это сделаю). Посему поставлена задача типа “работайте на этом говне”.

Но а если по сути - то Ваш способ действительно выдернет все данные до следующего тэга в коде страницы?
Я просто думал, чтобы ему поставить какое-то условие конкрентно на этот тэг типа если начало идет с “открывающая скобка” то начинай копировать все вплоть до нахождения “закрывающая скобка”.
S_K_Y_E
Добрый день! Прошу помощи, потому что у самого уже видимо замылен глаз и не вижу ошибку..
Есть кусок кода
 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()

До этого вверху код парсил страницы, в файл все сохранил, только теперь проблемы с извлечением этого всего в текстовый файл companies.txt. Не могу понять, почему скрипт это файл даже не создает + практически моментально закрывает окно (т.е. метод input() не срабатывает).

Гуру, ткните, пожалуйста, носом, может чего-то очевидного не вижу?
Заранее спасибо!
py.user.next
S_K_Y_E
даже не создает + практически моментально закрывает окно
Во второй строке перед pickle лишний отступ. Он определяет блок для with, и всё, что ниже, не принадлежит этому блоку, потому что отступ другой. А когда он доходит до следующей строки, с out2, он видит отступ в строке и не понимает, чей это отступ (отступ блока какой конструкции) и выдаёт синтаксическую ошибку. А синтаксические ошибки исключениями не считаются.

S_K_Y_E
практически моментально закрывает окно
Тебе надо научиться запускать программы в консоли (для этого открывать консоль отдельно). Тогда бы ты увидел, что там пишется.
S_K_Y_E
Спасибо большое за ответ!
Попробую изменить синтаксическую конструкцию и попробую еще раз

Про консоль вообще вылетело из головы, но потом додумался, и вот что выдает:


Т.е. это и есть синтаксическая ошибка?
py.user.next
S_K_Y_E
Т.е. это и есть синтаксическая ошибка?
Это уже другая ошибка. k - это не строка, а список.
S_K_Y_E
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()


Что меня сильно начало смущать - так это то, что данные после работы скрипта в файле показываются ну в очень странный способ:


Для разития руководствовался классическим подходом, создав пустой список и методом append (ну или extend вместе со split) разделить его по строкам по сепаратору “?”.

Может быть, где-то ошибочный подход?
py.user.next
S_K_Y_E
  
out.append([link, buf])
Ну, вот у тебя список добавляется в out. У тебя получается, что out - это список списков, где каждый список в out представляет из себя строку link и список строк buf. При переборе надо просто смотреть на элементы out как на списки, а не как на строки. А чтобы получить строки, нужно дальше раскладывать.

S_K_Y_E
Что меня сильно начало смущать - так это то, что данные после работы скрипта в файле показываются ну в очень странный способ:
Ну, это же формат pickle, там пишется служебная информация о каждом сохранённом объекте, чтобы потом его можно было точно восстановить. Список - это объект, строка - это объект, число - это объект. Объект обладает типом. При сохранении записывается всё об объектах и их вложенности.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB