Показ дописів із міткою python. Показати всі дописи
Показ дописів із міткою python. Показати всі дописи

pip install з параметрами

pip install mysqlclient --config-settings="build_options.c_options=-IC:\Program Files\MariaDB\MariaDB Connector C 64-bit\include 
-LC:\Program Files\MariaDB\MariaDB Connector C 64-bit\lib"

Таймаут для виконання функції в python

Є скрипт під віндою, який час від часу залипає і це є проблемою. Варіант вирішення - задавати час на виконання функції, якщо він перевищує поріг, вбивати виконання функції. Нагуглив кілька варіантів, але під віндою не працює SIGALRM. А цей сніп досить гарно працює.

import multiprocessing
import time

# bar
def bar():
    for i in range(100):
        print "Tick"
        time.sleep(1)

if __name__ == '__main__':
    # Start bar as a process
    p = multiprocessing.Process(target=bar)
    p.start()

    # Wait for 10 seconds or until process finishes
    p.join(10)

    # If thread is still active
    if p.is_alive():
        print "running... let's kill it..."

        # Terminate - may not work if process is stuck for good
        p.terminate()
        # OR Kill - will work for sure, no chance for process to finish nicely however
        # p.kill()

        p.join()

Очищення imap скриньки від старих листів

 
Прийшло таке дивне робоче повідомлення, але здивування було більше, коли в скрині виявилось 103 тисячі повідомлень.

Ділюсь скриптом, який за 5 хвилин видалив 70 тисяч повідомлень.


#!/usr/bin/python

MAIL_SERVER = 'mail.server.com'
USERNAME = 'login@domain.com'
PASSWORD = 'pass'
MAILBOX = 'INBOX'
MAX_DAYS = 392 # Deletes messages older than a week

import imaplib
import datetime

today = datetime.date.today()
cutoff_date = today - datetime.timedelta(days=MAX_DAYS)
before_date = cutoff_date.strftime('%d-%b-%Y')

search_args = '(BEFORE "%s")' % before_date

imap = imaplib.IMAP4(MAIL_SERVER)
imap.login(USERNAME, PASSWORD)
imap.select(MAILBOX)

typ, data = imap.search(None, 'ALL', search_args)

for num in data[0].split():
    print num
    imap.store(num, '+FLAGS', '\\Deleted')

imap.expunge()

imap.close()
imap.logout()

Автоматичний записувач ефіру радіостанції

Виникла ідея змайструвати найпростіший повторювач (репітер, попугай) за допомогою радіостанції, комп'ютера та невеличкої схеми.

Алгоритм працю наступним чином.
З радіостанції знімається звук через вихід на колонку шнуром з резисторним дільником та включеним в мікрофонний вхід ноутбука. Резисторний дільник потрібен щоб зменшити рівень сигналу з радіостанції, бо мікрофонний вхід досить чутливий. На ноутбуці працює наступний скрипт:


#!/bin/bash

while :
do
    ./rec.py
    DATE=`date +%Y%m%d%H%T`
    mv demo.wav demo-$DATE.wav
    #vlc demo-$DATE.wav &
    #killall -9 vlc
    echo "recorded $DATE"
done

і цикл, в якому відбувається запис та відтворювання записаного сигналу (останнє в стадії розробки). В гніздо навушників буде включено "дравйвер" реле, який буде слухати сигнал в навушниках і в разі його появи, реле буде спрацьовувати та імітувати натискання тангенти, також цей сигнал буде подаватись на мікрофонний вхід радіостанції. Що з того вийде, побачимо. На даний момент

і власне результат роботи скрипта:

Python-скрипт для видалення старих бекапів через FTP

#!/usr/bin/python

import time
import ftputil

host = ftputil.FTPHost('ftphost', 'ftpuser', 'ftppass')
mypath = ['/', '/dir1', '/dir2', '/dir3', '/dir3',] # директорії з яких видаляти бекапи
now = time.time()

for p in mypath:
    host.chdir(p)
    names = host.listdir(host.curdir)

    for name in names:
        if host.path.getmtime(name) < (now - (7 * 86400)): # 7 днів
            if host.path.isfile(name):
                host.remove(name)


print 'Closing FTP connection'
host.close()

vkontakte пост на власну стіну з аплоадом фотографії на python

session = vk.Session(access_token='blahblahblah')
api = vk.API(session)
upload_server = api.photos.getWallUploadServer()
r = requests.post(upload_server['upload_url'], files={'photo': open("/home/gsv/photo.jpg","rb")})
params = {'server': r.json()['server'], 'photo': r.json()['photo'], 'hash': r.json()['hash']}
wallphoto = api.photos.saveWallPhoto(**params)
photoID = wallphoto[0]['id']
params = {'attachments': str(photoID), 'message': 'Тест'}
api.wall.post(**params)

Python Selenium PhantomJS робота з Facebook

По замовчуванні PhantomJS на відріз відмовився працювати з Facebook, хоча webdriver.Firefox() працює прекрасно. Методом гугління, проб і помилок вияснилось, що проблема при роботі з SSL. Отже, робочий "сніпєтс":

dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = \
    ("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/53 (KHTML, like Gecko) Chrome/15.0.87")
wd = webdriver.PhantomJS(desired_capabilities=dcap, service_args=['--ssl-protocol=tlsv1'])
wd.set_window_size(1120, 550)
wd.get("https://www.facebook.com/")

Прочитати змінений скриптами DOM в Selenium

Простенькі сайти можна парсити через curl+lxml чи щось інше. Динамічні сайти, які генеруються за допомогою скриптів на стороні клієнта можна парсити через Selenium і отримувати код сторінки через driver.page_source. Але є ще більш комплексні сайти (наприклад Facebook), які після завантаження і генерації сторінки додатково змінюють DOM і page_source вже не допоможе. Для вирішення питання треба запустити скрипт:

outerhtml = wd.execute_script("return document.documentElement.outerHTML")
tree = etree.parse(StringIO(outerhtml), parser)

Скрапер weblancer.net на python+lxml

Колега попросив помогти знайти помилку в скрипті. Парсалось за допомогою BS, а я його ненавиджу. Переписав на lxml

#!/usr/bin/env python
#-*- coding: utf-8 -*-
 
import re
from lxml import etree
from lxml import html as lxml_html
import urllib2
from io import StringIO

_base_url = "https://www.weblancer.net/projects/?page={}"
def main():
    parser = lxml_html.HTMLParser(encoding='windows-1251')
    page =urllib2.urlopen(_base_url.format(1))
    data=page.read()
    tree = etree.parse(StringIO(data.decode("windows-1251", errors="ignore")), parser)

    last_page_url = tree.xpath("//ul[@class='pagination']/li[last()]/a/@href")[0]
    last_page = re.compile(r"(\d+)").search(last_page_url).group(1)

    for i in range(0, int(last_page)+1):
        page =urllib2.urlopen(_base_url.format(i))
        data=page.read()
        tree = etree.parse(StringIO(data.decode("windows-1251", errors="ignore")), parser)
        search_results = tree.xpath("//div[@class='container-fluid cols_table show_visited']/div[@class='row']")
        for sr in search_results:
            title =  sr.xpath("./div[@class='col-sm-7']/a[@class='title']/text()")[0].lstrip().rstrip()
            categories =  sr.xpath("./div[@class='col-sm-7']/div[@class='text-muted']/a[@class='text-muted']/text()")[0].lstrip().rstrip()
            try:
                price = sr.xpath("./div[@class='col-sm-2 amount title']/text()")[0].lstrip().rstrip()
            except IndexError:
                price = '' 
            try:
                application = sr.xpath("./div[@class='col-sm-3 text-right text-nowrap hidden-xs']/text()")[0].lstrip().rstrip()
            except IndexError:
                application = ''
            print title, categories, application, price

if __name__ == "__main__":
    main()

і ще один парсер

#!/usr/bin/env python

import re
import helpers
import hashlib
from lxml import etree
from lxml import html as lxml_html
from urlparse import urlparse

_base_url = "http://efccnigeria.org/efcc/index.php/wanted?limitstart={}"
_base_site_name = urlparse(_base_url)

def cleanhtml(raw_html):
    cleanr =re.compile('<.*?>')
    cleantext = re.sub(cleanr,'', raw_html)
    return cleantext

def parse_links(div_blog, iter):
    if iter == 0:
        div_blog = div_blog[:-2]
    else:
        div_blog = div_blog[:-1]

    links = []
    for db in div_blog:
        left_div = db.getchildren()[0].\
                      getchildren()[0].\
                      getchildren()[0].\
                      getchildren()[0].\
                      getchildren()[0].\
                      getchildren()[0].\
                      attrib.get('href')
        right_div = db.getchildren()[1].\
                      getchildren()[0].\
                      getchildren()[0].\
                      getchildren()[0].\
                      getchildren()[0].\
                      getchildren()[0].\
                      attrib.get('href')
        links.append("%s://%s%s" % (_base_site_name[0], _base_site_name[1], left_div))
        links.append("%s://%s%s" % (_base_site_name[0], _base_site_name[1], right_div))
    return links

def build_document(content):
    name = content[0].getchildren()[0].text.lstrip().rstrip()
    description = etree.tostring(content[2].getchildren()[0], encoding="utf-8")
    description_clean = cleanhtml(description)
    description_clean = re.sub('\&\#13\;', '', description_clean)
    description_clean = re.sub('\xc2\xa0', '', description_clean)
    description_clean = "\n".join([ll.rstrip() for ll in description_clean.splitlines() if ll.strip()]) # strip blank lines
    description_clean = description_clean.split("\n")
    index = description_clean.index(' <!--')
    description_clean = description_clean[:index]
    description_clean = ' '.join(description_clean)

    entity = {
        "_meta": {
            "id": hashlib.sha224((re.sub("[^a-zA-Z0-9]", "", name + description_clean.decode("utf8", errors="ignore")))).hexdigest(),
            "entity_type": "person"
        },
        "name": name,
        "types": ["pep"],
        "fields": [
            {"name": "Description", "value": description_clean.decode("utf8", errors="ignore")}
        ]
    }
    helpers.emit(entity)

def main():
    parser = lxml_html.HTMLParser(encoding='utf-8')

    tree = etree.parse(_base_url.format(0), parser)
    last_page_url = tree.findall("//li[@class='pagination-end']/a")[0].attrib.get('href')
    rx_sequence=re.compile(r"start=([0-9]+)")
    last_page = rx_sequence.search(last_page_url).group(1)

    for i in range(0, int(last_page)+1, 20):
        tree = etree.parse(_base_url.format(i), parser)
        div_blog = tree.findall("//div[@class='blog']/div")
        links = parse_links(div_blog, i)
        for link in links:
            tree = etree.parse(link, parser)
            xpath = "/html/body/div[2]/div[2]/div/div[5]/div/div/div[2]/div[2]/div/div/div[1]"
            person_info = tree.xpath(xpath)[0].getchildren()
            build_document(person_info)

if __name__ == "__main__":
    main()

Парсер

#!/usr/bin/env python

import re
import helpers
import hashlib
from lxml import etree
from lxml import html as lxml_html

_base_url = "http://guernseyregistry.com/article/4036/Disqualified-Directors"

def check_children(element):
    if element.getchildren():
        return element.getchildren()[0].text
    return element.text

def build_document(member):
    date_of_disqualification, \
    applicant_for_disqualification, \
    name_of_disqualified_director, \
    period_of_disqualification, \
    end_of_disqualification_period =  [check_children(member[i]) for i in range(0, 5)]

    entity = {
        "_meta": {
            "id": hashlib.sha224((re.sub("[^a-zA-Z0-9]", "", name_of_disqualified_director + date_of_disqualification))).hexdigest(),
            "entity_type": "person"
        },
        "name": name_of_disqualified_director,
        "types": ["pep"],
        "fields": [
            {"name": "Date of disqualification", "value": date_of_disqualification},
            {"name": "Applicant for disqualification", "value": applicant_for_disqualification},
            {"name": "Period of disqualification", "value": period_of_disqualification},
            {"name": "End of disqualification period", "value": end_of_disqualification_period}
        ]
    }
    helpers.emit(entity)

def main():
    parser = lxml_html.HTMLParser(encoding='utf-8')
    tree = etree.parse(_base_url, parser)
    table = tree.findall("//table[@summary='disqual directors']/tbody/tr")
    for tr in table[1:]:
        build_document(tr.getchildren())

if __name__ == "__main__":
    main()

Очистка HTML від зайвих тегів та атрибутів

Один з напрямків моєї роботи - контент менеджмент (іншими словами, набивка сайтів інформацією). Коли на сайт потрібно закинути звичайний текст з абзацами, все просто і швидко відбувається, а коли потрібно копіпастнути якусь табличку, приміром, взяту з іншого сайту, то це займає багато часу, так як мені потрібен чистий HTML-код без зайвих тегів та атрибутів, щоб жодним чином копіпаст не впливав на дизайн мого сайту. Раніше користувався автозаміною на "пустоту", але це теж не вихід. Сьогодні мене остаточно трафили шляки і вирішив повністю автоматизувати процедуру але для командної стрічки. Є ідея зробити онлайн сервіс, яким зможуть користуватись такі самі контент менеджери як і я. Питання лише, чи дійсно комусь це може полегшити життя? Це можна оформити у вільному доступі на веб-сайті з кількома формами, галочками і пімпочками та миттєвим результатом-відфільтрованим HTML-текстом.

Тепер наглядно поясню принцип роботи скрипта, написаного на Python

Є кусок HTML:

Необхідно забрати теги: a, p, span, div, strong
і атрибути: class, width, cellspacing, cellpadding, border

Код програми:
from lxml import etree
from lxml import html as lxml_html
from lxml.html import clean, fromstring, tostring, _transform_result, copy

remove_attrs = ['class', 'width', 'cellspacing', 'cellpadding', 'border']
remove_tags = ['a', 'p', 'span', 'div', 'strong']
nonempty_tags = []

class MyCleaner(clean.Cleaner):
    def clean_html(self, html, parser=None):
        result_type = type(html)
        if isinstance(html, basestring):
            doc = fromstring(html, parser=parser)
        else:
            doc = copy.deepcopy(html)
        self(doc)
        return _transform_result(result_type, doc)

cleaner = MyCleaner(remove_tags=remove_tags, page_structure=False)

def squeaky_clean(html):
    parser = lxml_html.HTMLParser(encoding='utf-8')

    clean_html = cleaner.clean_html(html, parser)
    root = fromstring(clean_html)
    context = etree.iterwalk(root)

    for action, elem in context:
        clean_text = elem.text and elem.text.strip(' \t\r\n')

        if elem.tag in nonempty_tags and \
        not (len(elem) or clean_text):
            elem.getparent().remove(elem)
            continue
        elem.text = clean_text

        for badattr in remove_attrs:
            if elem.attrib.has_key(badattr):
                del elem.attrib[badattr]

    return tostring(root, encoding='ISO-8859-1')

html = squeaky_clean(DATA)
print html
І на виході маємо результат:

Кілька версій Django на одній системі

Стикнувся з проблемкою, коли потрібно одночасно розробляти кілька проектів під різні версії Django. Один з варіантів вирішення: felecan.com/2011/definitive-guide-installing-django-ubuntu/

files list file for package 'xxx' is missing final newline

Сьогодні при оновленні Ubuntu отримав САБЖ помилку. Наступний вигуглений скрипт вирішує проблему.
#!/usr/bin/python


# 8th November, 2009
# update manager failed, giving me the error:
#       'files list file for package 'xxx' is missing final newline' for every package.
# some Googling revealed that this problem was due to corrupt files(s) in /var/lib/dpkg/info/
# looping though those files revealed that some did not have a final new line
# this script will resolve that problem by appending a newline to all files that are missing it
# NOTE: you will need to run this script as root, e.g. sudo python newline_fixer.py

import os

dpkg_path = '/var/lib/dpkg/info/'
paths = os.listdir(dpkg_path)
for path in paths:
    path = dpkg_path + path
    f = open(path, 'a+')
    data = f.read()
    if len(data) > 1 and data[-1:] != '\n':
        f.write('\n')
        print 'added newline character to:', path
    f.close() 

Багатопотокова проксі-чекалка на Python

#!/usr/bin/python

import Queue
import threading
import MySQLdb
import urllib2
import time

class DB:
    conn = None
    def connect(self):
        self.conn = MySQLdb.connect(host = "x.y.z.q", user = "user", passwd = "password", db = "database")
    def query(self, sql):
        try:
            cursor = self.conn.cursor()
            cursor.execute(sql)
        except (AttributeError, MySQLdb.OperationalError):
            self.connect()
            cursor = self.conn.cursor()
            cursor.execute(sql)
        return cursor

proxyList = []

global db
db = DB()
curr = db.query("SELECT url FROM proxy")
result_set = curr.fetchall ()
for row in result_set:
    proxyList.append(row[0])

queue = Queue.Queue()

class ThreadUrl(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            host = self.queue.get()
            try:
                proxy_handler = urllib2.ProxyHandler({'http':host})
                opener = urllib2.build_opener(proxy_handler)
                opener.addheaders = [('User-agent','Mozilla/5.0')]
                urllib2.install_opener(opener)
                req = urllib2.Request("http://www.proxylists.net/proxyjudge.php")
                sock=urllib2.urlopen(req, timeout= 7)
                rs = sock.read(5000)
                if 'ProxyLists.Net - Proxy judge' in rs:
                    print "ok %s" % host
                    db.query("UPDATE proxy SET checked=NOW() WHERE url = '%s' " % host)

            except:
                print "err %s" % host
                db.query("DELETE FROM proxy WHERE url LIKE '%s' " % host)

            self.queue.task_done()

def main():
    for i in range(20):
        t = ThreadUrl(queue)
        t.setDaemon(True)
        t.start()

    for host in proxyList:
        queue.put(host)

    queue.join()

main()

аплоад файлів на Youtube через консоль

Завалялось 80 гіг відео на одному віддаленому сервері. Виявляється, все просто:
# apt-get install python-gdata python-progressbar
Качаємо скрипт: http://code.google.com/p/youtube-upload/
youtube-upload --email=myemail@gmail.com --password=mypassword 
                 --title="A.S. Mutter" --description="A.S. Mutter plays Beethoven" 
                 --category=Music --keywords="mutter, beethoven" anne_sophie_mutter.flv
І що найцікавіше, то можна задавати маску для файлів і одною командою завантажити весь каталог файлів.