| class MyHTMLParser(HTMLParser):
| def __init__(self, site_name, * args, * * kwargs):
| # список ссылок
| self.links = []
| # имя сайта
| self.site_name = site_name
| # вызываем __init__ родителя
| super().__init__( * args, * * kwargs)
| # при инициализации "скармливаем" парсеру содержимое страницы
| self.feed(self.read_site_content())
| # записываем список ссылок в файл
self.write_to_file()
Базовый класс HTMLParser имеет несколько методов, нас в данном случае интересуют метод handle_start_tag. Этот метод вызывается каждый раз, когда наш парсер встречает в тексте октрывающий html-тэг.
| def handle_starttag(self, tag, attrs):
| # проверяем является ли тэг тэгом ссылки
| if tag == 'a':
| # находим аттрибут адреса ссылки
| for attr in attrs:
| if attr[0] = = 'href':
| # проверяем эту ссылку методом validate() (мы его еще напишем)
| if not self.validate(attr[0]):
| # вставляем адрес в список ссылок
self.links.append(attr[1])
Напишем вспомогательный метод validate:
| def validate(self, link):
| """ Функция проверяет стоит ли добавлять ссылку в список адресов.
| В список адресов стоит добавлять если ссылка:
| 1) Еще не в списке ссылок
| 2) Не вызывает javascript-код
| 3) Не ведет к какой-либо метке. (Не содержит #)
| """
return link in self.links or'#'inlink or'javascript:' inlink
Создадим метод, который будет открывать указанную страницу и выдавать ее содержимое.
def read_site_content(self):
return str(urlopen(self.site_name).read())
Осталось добавить возможность записи списка ссылок на диск в читабельном формате:
| def write_to_file(self):
| # открываем файл
| f =open('links.txt', 'w')
| # записываем отсортированный список ссылок, каждая с новой строки
| f.write('\n'.join(sorted(self.links)))
| # закрываем файл
f.close()
Все готово, можем запускать парсер.
| parser = MyHTMLParser("http://python.org")
После того как вы запустите данный скрипт в директории, где находится ваш файл появится текстовый документ links.txt, содержащий ссылки.
Конечно, данный пример достаточно примитивен, но на его основе вы можете попробовать написать, к примеру, веб-crawler, который будет анализировать весь сайт целиком, а не одну его страницу.
Примитивный Paint на Python
создании GUIмакетов компоновки в tkinterдополнительных аргументов в функцию-обработчикlambda-функции в PythonДля этого примера удобнее будет использовать классовый подход к созданию GUI. Для начала определим класс Paint:
| from tkinter import *
| class Paint(Frame):
| def __init__(self, parent):
| Frame.__init__(self, parent)
| self.parent = parent
| def main():
| root = Tk()
| root.geometry("1920x1080+300+300")
| app = Paint(root)
| root.mainloop()
| if __name__ == "__main__":
| main()
Запустив этот код вы должны получить простенькое окно, с которым мы будем работать дальше.
Теперь напишем для класса Paint метод setUI, в котором будет задаваться расположение всех кнопок, меток и самого поля для рисования. У нас будет два ряда кнопок, первый ряд с кнопками устанавливающими цвет, второй ряд устанавливает размер кисти для рисования. Под ними будет идти поле для рисования.
Это достаточно объемный метод, однако многие строки повторяются, так что наберитесь терпения:
| def setUI(self):
| self.parent.title("Pythonicway PyPaint") # Устанавливаем название окна
| self.pack(fill=BOTH, expand=1) # Размещаем активные элементы на родительском окне
|
| self.columnconfigure(6, weight=1)
# Даем седьмому столбцу возможность растягиваться, благодаря чему кнопки не будут разъезжаться при ресайзе | self.rowconfigure(2, weight=1) # То же самое для третьего ряда
| self.canv = Canvas(self, bg="white") # Создаем поле для рисования, устанавливаем белый фон
| self.canv.grid(row=2, column=0, columnspan=7,
| padx=5, pady=5, sticky=E+W+S+N)
# Прикрепляем канвас методом grid. Он будет находится в 3м ряду, первой колонке, и будет занимать 7 колонок, задаем отступы по X и Y в 5 пикселей, и заставляем растягиваться при растягивании всего окна | color_lab = Label(self, text="Color: ") # Создаем метку для кнопок изменения цвета кисти
| color_lab.grid(row=0, column=0, padx=6)
# Устанавливаем созданную метку в первый ряд и первую колонку, задаем горизонтальный отступ в 6 пикселей
| red_btn = Button(self, text="Red", width=10)
# Создание кнопки: Установка текста кнопки, задание ширины кнопки (10 символов) | red_btn.grid(row=0, column=1) # Устанавливаем кнопку первый ряд, вторая колонка
|
| # Создание остальных кнопок повторяет ту же логику, что и создание
| # кнопки установки красного цвета, отличаются лишь аргументы.
|
| green_btn = Button(self, text="Green", width=10)
| green_btn.grid(row=0, column=2)
| blue_btn = Button(self, text="Blue", width=10)
| blue_btn.grid(row=0, column=3)
|
| black_btn = Button(self, text="Black", width=10)
| black_btn.grid(row=0, column=4)
|
| white_btn = Button(self, text="White", width=10)
| white_btn.grid(row=0, column=5)
| size_lab = Label(self, text="Brush size: ") # Создаем метку для кнопок изменения размера кисти
| size_lab.grid(row=1, column=0, padx=5)