Skip to content

Instantly share code, notes, and snippets.

@mr-linch
Last active November 4, 2023 18:17
Show Gist options
  • Star 43 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save mr-linch/ea6803f8df5d3805464a to your computer and use it in GitHub Desktop.
Save mr-linch/ea6803f8df5d3805464a to your computer and use it in GitHub Desktop.
Исходный код для урока (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
Copy link

Ondrya commented Oct 13, 2015

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

@LllxNik
Copy link

LllxNik commented Feb 4, 2016

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

@savandriy
Copy link

Ошибка в функции 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
Copy link
Author

mr-linch commented Mar 1, 2016

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

@mr-linch
Copy link
Author

mr-linch commented Mar 1, 2016

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

VK
Telegram

@luk911
Copy link

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
Copy link

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
Copy link

vbcmrj1 commented May 17, 2016

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

@maksymkv25
Copy link

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

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

@semchupin
Copy link

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
Copy link

RoxVell commented Jul 11, 2016

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

@semchupin
Copy link

semchupin commented Jul 12, 2016

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

@semchupin
Copy link

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

@vladimirmyshkovski
Copy link

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

@Liferenko
Copy link

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

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

@Liferenko
Copy link

Liferenko commented Nov 2, 2016

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

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

@superpuperuser
Copy link

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
Copy link

Подскажите, пожалуйста, в чем причина ошибки
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
Copy link

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