Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Исходный код для урока (https://youtu.be/KPXPr-KS-qk)
#!/usr/bin/env python3
import csv
import urllib.request
from bs4 import BeautifulSoup
BASE_URL = 'http://www.weblancer.net/projects/'
def get_html(url):
response = urllib.request.urlopen(url)
return response.read()
def get_page_count(html):
soup = BeautifulSoup(html)
paggination = soup.find('div', class_='pages_list text_box')
return int(paggination.find_all('a')[-2].text)
def parse(html):
soup = BeautifulSoup(html)
table = soup.find('table', class_='items_list')
rows = table.find_all('tr')[1:]
projects = []
for row in rows:
cols = row.find_all('td')
projects.append({
'title': cols[0].a.text,
'categories': [category.text for category in cols[0].find_all('noindex')],
'price': cols[1].text.strip().split()[0],
'application': cols[2].text.split()[0]
})
return projects
def save(projects, path):
with open(path, 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(('Проект', 'Категории', 'Цена', 'Заявки'))
writer.writerows(
(project['title'], ', '.join(project['categories']), project['price'], project['application']) for project in projects
)
def main():
total_pages = get_page_count(get_html(BASE_URL))
print('Всего найдено %d страниц...' % total_pages)
projects = []
for page in range(1, total_pages + 1):
print('Парсинг %d%% (%d/%d)' % (page / total_pages * 100, page, total_pages))
projects.extend(parse(get_html(BASE_URL + "page=%d" % page)))
print('Сохранение...')
save(projects, 'projects.csv')
if __name__ == '__main__':
main()
@Ondrya

This comment has been minimized.

Copy link

@Ondrya Ondrya commented Oct 13, 2015

Предлагаю заменить urllib на библиотеку requests
Когда страница большая - выпадает ошибка чтения периодически.

@LllxNik

This comment has been minimized.

Copy link

@LllxNik LllxNik commented Feb 4, 2016

Александр, как можно с вами связаться?

@savandriy

This comment has been minimized.

Copy link

@savandriy savandriy commented Feb 19, 2016

Ошибка в функции get_html, должно быть так:

def get_html(url):
    response = urllib.request.urlopen(url)
    return response.read()

Можно сделать иначе, к примеру просто не передавать параметры в функцию:

def get_html():
    response = urllib.request.urlopen(BASE_URL)
    return response.read()
@mr-linch

This comment has been minimized.

Copy link
Owner Author

@mr-linch mr-linch commented Mar 1, 2016

@savandriy спасибо, поправил)

@mr-linch

This comment has been minimized.

Copy link
Owner Author

@mr-linch mr-linch commented Mar 1, 2016

@LllxNik Да, конечно

VK
Telegram

@luk911

This comment has been minimized.

Copy link

@luk911 luk911 commented Apr 12, 2016

перерыл весь интернет не нашел, не знаю у кого спросить: Получаю html - и он уже приходит с переносами строк \n , как их убрать не знаю, собственно функцию которую использую

def get_article(html):
    soup = BeautifulSoup(html, "html.parser")
    untranslate = soup.find('div', class_='thecontent')

на выходе получаю между html тегами переносы строк

<p>While many fruits and vegetables are excellent sources of fiber, be aware that they may also contain high levels of oxalate which is one of the major causes of kidney stones. Read more about high-oxalate foods in </p>\n
<h4><strong>8. Kidney Beans</strong></h4>\n
<p>On a similar note (and somewhat ironically) Kidney beans – so called for their resemblance in shape and color to the same-named organ – are also great for clearing up kidney stones.</p>\n
</div>

Все бы ничего, но когда в переводчик засовываю, тот странно себя ведет, половину тегов съедает.

Как удалить эти \n ?? может люди добрые подскажут ?

@bugap

This comment has been minimized.

Copy link

@bugap bugap commented May 2, 2016

@luk911 Я только начал осваивать Python, но может так поможет:

html = """<p>While many fruits and vegetables are excellent sources of fiber, be aware that they may also contain high levels of oxalate which is one of the major causes of kidney stones. Read more about high-oxalate foods in </p>\n
<h4><strong>8. Kidney Beans</strong></h4>\n
<p>On a similar note (and somewhat ironically) Kidney beans – so called for their resemblance in shape and color to the same-named organ – are also great for clearing up kidney stones.</p>\n
</div>"""

print(html.replace('\n', ''))
@vbcmrj1

This comment has been minimized.

Copy link

@vbcmrj1 vbcmrj1 commented May 17, 2016

Дякую за урок на Ю тубі)))...супер...

@maksymkv25

This comment has been minimized.

Copy link

@maksymkv25 maksymkv25 commented May 25, 2016

return int(paggination.find_all('a')[-2].text)

как сделать поиск не по тексту, а именно по ссылке, потому что сайт переделали и в поле текста уже не хранится количество всех страниц

@semchupin

This comment has been minimized.

Copy link

@semchupin semchupin commented Jul 9, 2016

Доброго времени суток
Извиняюсь за наверное глупый вопрос но всё же что в этом коде неправильно

`

!/usr/bin/env python3

import csv
import urllib.request
from bs4 import BeautifulSoup
BASE_URL = 'http://www.limango.de/shop/overview/24079'
def get_html():
response = urllib.request.urlopen(BASE_URL)
return response.read()
def get_page_count(html):
soup = BeautifulSoup(html)
paggination = soup.find('div', class_='result-controls position-bottom')
return int(paggination.find_all('a')[-1].text)
def parse(html):
soup = BeautifulSoup(html)
table = soup.find('div', class_='result')
rows = table.find_all('div')
projects = []
for row in rows:
cols = row.find_all('span')
projects.append({
'title': cols[0].span.text,
'categories': [category.text for category in cols[0].find_all('span.value')],
'price': cols[1].text.strip().split()[0],
})
return projects
def save(projects, path):
with open(path, 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(('Продукт', 'Категория', 'Цена'))
writer.writerows(
(project['title'], ', '.join(project['categories']), project['price']) for project in projects
)
def main():
total_pages = get_page_count(get_html(BASE_URL))
print('Всего найдено %d страниц...' % total_pages)
projects = []
for page in range(1, total_pages + 1):
print('Парсинг %d%% (%d/%d)' % (page / total_pages * 100, page, total_pages))
projects.extend(parse(get_html(BASE_URL + "&page=%d" % page)))
print('Сохранение...')
save(projects, 'projects.csv')
`

@RoxVell

This comment has been minimized.

Copy link

@RoxVell RoxVell commented Jul 11, 2016

@semchupin Прежде чем парсить сайт, на нём нужно авторизоваться

@semchupin

This comment has been minimized.

Copy link

@semchupin semchupin commented Jul 12, 2016

@RoxVell я авторизован на сайте

@semchupin

This comment has been minimized.

Copy link

@semchupin semchupin commented Jul 17, 2016

@RoxVell или ты имел ввиду то что авторизацию можно прописать в коде?

@vladimirmyshkovski

This comment has been minimized.

Copy link

@vladimirmyshkovski vladimirmyshkovski commented Sep 20, 2016

Пишите мне https://vk.com/id246362627 , помогу разобраться.

@Liferenko

This comment has been minimized.

Copy link

@Liferenko Liferenko commented Nov 2, 2016

для новичков в Питоне.

Сайт-"жертву" переделали. Для тех, кто повторяет за видео (как я) может быть проблемой, что в результате получается не такой код, который на видео. Причина - переделанный сайт веблансера. Там теперь почти нет table, td, tr (и слава богу, что нет).
То есть во время следования по видео всё-таки стОит присматриваться к исходному коду сайта-"жертвы".

@Liferenko

This comment has been minimized.

Copy link

@Liferenko Liferenko commented Nov 2, 2016

В комментариях на Youtube выложили актуальный на сентябрь 2016 года код.

https://www.youtube.com/watch?v=KPXPr-KS-qk&lc=z13gedpjyxe2unbly23ozxlgfyapwxg33

@superpuperuser

This comment has been minimized.

Copy link

@superpuperuser superpuperuser commented Nov 11, 2016

Не могу разобраться с записью в файл, делал для другого сайта правда, но не суть. У меня получилось 3 категории, и при записи в csv, не идет разбиение на столбцы, все категории записываются без соблюдения полей, просто через запятую. Подскажите пожалуйста, в чем может быть ошибка?

def save(self, path):
projects = self.parsing()
with open(path, 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(('Порода', 'Цена', 'Время'))

@llirikkcoder

This comment has been minimized.

Copy link

@llirikkcoder llirikkcoder commented May 30, 2019

Подскажите, пожалуйста, в чем причина ошибки
weblancer.py:18: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system ("html.parser"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.

The code that caused this warning is on line 18 of the file weblancer.py. To get rid of this warning, pass the additional argument 'features="html.parser"' to the BeautifulSoup constructor.

soup = BeautifulSoup(html)
Traceback (most recent call last):
File "weblancer.py", line 68, in
main()
File "weblancer.py", line 53, in main
total_pages = get_page_count(get_html(BASE_URL))
File "weblancer.py", line 20, in get_page_count
return int(paggination.find_all('a')[-2].text)
AttributeError: 'NoneType' object has no attribute 'find_all'

@777Raim

This comment has been minimized.

Copy link

@777Raim 777Raim commented Jun 8, 2019

@llirikkcoder, если еще актуально, то ошибка вываливается из-за того, что сайт перешел на другую структуру html-кода. Этот парсер пытается найти блоки с несуществующими классами и т.д.

Ниже мой вариант рабочего парсера:

#!/usr/bin/env python3

import csv
import requests

from bs4 import BeautifulSoup


BASE_URL = 'https://www.weblancer.net/jobs/'


def get_html(url):
    response = requests.get(url)
    if response.status_code == 200:
        return response.content
    else:
        print ("Error")
        quit()


def get_page_count(html):
    soup = BeautifulSoup(html, features="lxml")
    paggination = soup.find('div', class_='pagination_box')
    return int(paggination.find_all('a')[-1]['href'].split("=")[1])


def parse(html):
    soup = BeautifulSoup(html, features="lxml")
    table = soup.find('div', class_='page_content').find('div', class_='cols_table')

    rows = table.find_all('div', class_='row')

    projects = []
    nmbr = 1
    for row in rows:

        # Знак валюты в конец строки
        price = row.find('div', class_='float-right float-sm-none title amount indent-xs-b0').text
        if price != '':
            price=price[1:]+price[0]

        projects.append({
            'title': row.find('h2').text,
            'short_description': row.find('p').text,
            'categories': [category.text for category in row.find('div', class_='col-sm-8 text-muted dot_divided').find_all('a')],
            'price': price,
            'application': row.find('div', class_='float-left float-sm-none text_field').text.strip()
        })

    return projects

def save(projects, path):
    with open(path, 'w') as csvfile:
        writer = csv.writer(csvfile)

        writer.writerow(('Проект', 'Краткое описание', 'Категории', 'Цена', 'Заявки'))

        writer.writerows(
            (project['title'], project['short_description'], project['categories'], project['price'], project['application']) for project in projects
        )

def main():

    total_pages = get_page_count(get_html(BASE_URL))

    print('Всего найдено %d страниц...' % total_pages)

    projects = []

    for page in range(1, total_pages + 1):
        print('Парсинг %d%% (%d/%d)' % (page / total_pages * 100, page, total_pages))
        projects.extend(parse(get_html(BASE_URL + "?page=%d" % page)))

    print('Сохранение...')
    save(projects, 'projects.csv')
    print('Готово!')


if __name__ == '__main__':
    main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.