I am currently using aiohttp and lxml to scrape webpages and return values. So far, I have
def get_sr(page, tree):
sr = tree.xpath(".//div[#class='competitive-rank']/div/text()")[0]
return sr
def get_icon_url(page, tree):
url = tree.xpath('.//img[#class="player-portrait"]/#src')[0]
return url
def get_sr_icon_url(page, tree):
url = tree.xpath('.//div[#class="competitive-rank"]/img/#src')[0]
return url
def get_level(page, tree):
level = tree.xpath('.//div[#class="header-avatar"]/text()')[0]
return level
The first 3 functions work perfectly, and yet the final function will not correctly get the text I am looking for. This:
<div class="header-avatar">
<img src="https://blzgdapipro-a.akamaihd.net/game/unlocks/0x0250000000001150.png" width="80" height="80">
<span>369</span>
</div>
Is the code block I am trying to get the number from. Currently, the number is 369 but it constantly changes. I have confirmed that the page and tree are correct through print statements, so instead it's an issue w/ the actual get_level method itself.
Help? Other pieces of code needed to determine issue?
Thank you for the help.
Try this:
level = tree.xpath('.//div[#class="header-avatar"]/span/text()')[0]
I would like to use a class Track to have a function playsound() and this should play the sound on a html template.
This is my class :
class Track:
def __init__(self, name, path):
self.name = name
self.path = path
def playsound(self):
# does something
Now I know that I will need javascript and ajax as well probably. But I'm still new to the concept and I would like to see how I would go about achieving that. The sound file should play onload and should simply be invoked when you type:
songname = Track('name', 'music/filename.ogg')
#app.route('/playSong')
def playSong():
return songname.play()
If there is no way this can be done in this way, or there is a much better way, I'd be happy to be enlightened. Thanks in advance!
You can keep the src of in HTML as
<audio controls>
<source src="http://127.0.0.1:5000/a" type="audio/wav"/>
</audio>
where http://127.0.0.1:5000/a is the url which send_file the audio
python code :
#app.route('/a')
def returnAudioFile():
path_to_audio_file = pwd+"\\question_folder\\audio.wav" #audio from project dir
return send_file(
path_to_audio_file,
mimetype="audio/wav",
as_attachment=True,
attachment_filename="test.wav")
If I understood the question correctly, you should put an <audio> HTML element in your template and go from there. Flask will only serve the rendered template, it can't play the sound directly.
I'm trying just for learning how to serve a video with the blobstore without it takes all the screen the video, for example
here I imported Video as video_model
class ViewVideo(webapp.Reque...,blobstore_handlers.BlobstoreDownloadHandler):
def get(self):
video_id = self.request.get('video_id')
video_instance = None
if video_id:
video_instance = video_model().get_video_content(video_id)
self.response.headers['Content-Type'] = 'video/mp4'
self.send_blob(video_instance.content.key())
class Video(db.Model):
content = blobstore.BlobReferenceProperty()
title = db.StringProperty()
def get_video(self,video_id):
return Video.get_by_id(video_id)
def get_video_content(self,content):
query_str = "SELECT * FROM Video WHERE content =:content"
return db.GqlQuery(query_str,content=content).get()
Where the video_id came from a url given, but as you see I put it directly in send_blob() function and this one when I tested it takes all the screen just to see the video, I was wondering how can I serve the video from my application without happening this, I was thinking embedded HTML but I can't figure it out how the source will be
Any help will be grateful
If it lacks of content to answer the question I will edit it
Without HTML5, it's a tricky mess. With HTML5, it becomes easy & elegant. Serve to the user's browser, as part of whatever page you're serving, the following HTML (5) snippet:
<video width="320" height="240" controls>
<source src="/getmp4?video_id=whatever" type="video/mp4">
Your browser does not support the video tag: please upgrade it!
</video>
and use that ViewVideo handler to serve only the /getmp4 URL, not the URL that your user directly gets via their browser.
The 320, 240, and the choice to show controls, are all optional, of course -- as even more is the use of whatever for the video id!-)
Im trying to display the content of a text file in a template without any luck so far. This is
my code so far:
#route('/show_article/<filename>')
def show_article(filename):
stat_art=static_file(filename, root="articles")
return template('show_article', stat_art=stat_art)
And this is the paragraph in my template to display the content of the file
<p>
{{stat_art}}
</p>
I know that I could just return the static_file() but I will need to design the page with
some css and stuff later.
Thanks in advance and sorry for if my english is not correct!
You've misunderstood what static_file does.
Luckily, the fix is simple: just read the file yourself and pass its contents to the template, like so:
#route('/show_article/<filename>')
def show_article(filename):
with open(filename) as f: # <-- you'll need the correct path here, possibly including "articles"
stat_art = f.read()
return template('show_article', stat_art=stat_art)
That should do the trick.
[Btw, nice first question!]
In python, what is the most elegant way to generate HTML documents. I currently manually append all of the tags to a giant string, and write that to a file. Is there a more elegant way of doing this?
You can use yattag to do this in an elegant way. FYI I'm the author of the library.
from yattag import Doc
doc, tag, text = Doc().tagtext()
with tag('html'):
with tag('body'):
with tag('p', id = 'main'):
text('some text')
with tag('a', href='/my-url'):
text('some link')
result = doc.getvalue()
It reads like html, with the added benefit that you don't have to close tags.
I would suggest using one of the many template languages available for python, for example the one built into Django (you don't have to use the rest of Django to use its templating engine) - a google query should give you plenty of other alternative template implementations.
I find that learning a template library helps in so many ways - whenever you need to generate an e-mail, HTML page, text file or similar, you just write a template, load it with your template library, then let the template code create the finished product.
Here's some simple code to get you started:
#!/usr/bin/env python
from django.template import Template, Context
from django.conf import settings
settings.configure() # We have to do this to use django templates standalone - see
# http://stackoverflow.com/questions/98135/how-do-i-use-django-templates-without-the-rest-of-django
# Our template. Could just as easily be stored in a separate file
template = """
<html>
<head>
<title>Template {{ title }}</title>
</head>
<body>
Body with {{ mystring }}.
</body>
</html>
"""
t = Template(template)
c = Context({"title": "title from code",
"mystring":"string from code"})
print t.render(c)
It's even simpler if you have templates on disk - check out the render_to_string function for django 1.7 that can load templates from disk from a predefined list of search paths, fill with data from a dictory and render to a string - all in one function call. (removed from django 1.8 on, see Engine.from_string for comparable action)
If you're building HTML documents than I highly suggest using a template system (like jinja2) as others have suggested. If you're in need of some low level generation of html bits (perhaps as an input to one of your templates), then the xml.etree package is a standard python package and might fit the bill nicely.
import sys
from xml.etree import ElementTree as ET
html = ET.Element('html')
body = ET.Element('body')
html.append(body)
div = ET.Element('div', attrib={'class': 'foo'})
body.append(div)
span = ET.Element('span', attrib={'class': 'bar'})
div.append(span)
span.text = "Hello World"
if sys.version_info < (3, 0, 0):
# python 2
ET.ElementTree(html).write(sys.stdout, encoding='utf-8',
method='html')
else:
# python 3
ET.ElementTree(html).write(sys.stdout, encoding='unicode',
method='html')
Prints the following:
<html><body><div class="foo"><span class="bar">Hello World</span></div></body></html>
There is also a nice, modern alternative: airium: https://pypi.org/project/airium/
from airium import Airium
a = Airium()
a('<!DOCTYPE html>')
with a.html(lang="pl"):
with a.head():
a.meta(charset="utf-8")
a.title(_t="Airium example")
with a.body():
with a.h3(id="id23409231", klass='main_header'):
a("Hello World.")
html = str(a) # casting to string extracts the value
print(html)
Prints such a string:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8" />
<title>Airium example</title>
</head>
<body>
<h3 id="id23409231" class="main_header">
Hello World.
</h3>
</body>
</html>
The greatest advantage of airium is - it has also a reverse translator, that builds python code out of html string. If you wonder how to implement a given html snippet - the translator gives you the answer right away.
Its repository contains tests with example pages translated automatically with airium in: tests/documents. A good starting point (any existing tutorial) - is this one: tests/documents/w3_architects_example_original.html.py
I would recommend using xml.dom to do this.
http://docs.python.org/library/xml.dom.html
Read this manual page, it has methods for building up XML (and therefore XHTML). It makes all XML tasks far easier, including adding child nodes, document types, adding attributes, creating texts nodes. This should be able to assist you in the vast majority of things you will do to create HTML.
It is also very useful for analysing and processing existing xml documents.
Here is a tutorial that should help you with applying the syntax:
http://www.postneo.com/projects/pyxml/
I am using the code snippet known as throw_out_your_templates for some of my own projects:
https://github.com/tavisrudd/throw_out_your_templates
https://bitbucket.org/tavisrudd/throw-out-your-templates/src
Unfortunately, there is no pypi package for it and it's not part of any distribution as this is only meant as a proof-of-concept. I was also not able to find somebody who took the code and started maintaining it as an actual project. Nevertheless, I think it is worth a try even if it means that you have to ship your own copy of throw_out_your_templates.py with your code.
Similar to the suggestion to use yattag by John Smith Optional, this module does not require you to learn any templating language and also makes sure that you never forget to close tags or quote special characters. Everything stays written in Python. Here is an example of how to use it:
html(lang='en')[
head[title['An example'], meta(charset='UTF-8')],
body(onload='func_with_esc_args(1, "bar")')[
div['Escaped chars: ', '< ', u'>', '&'],
script(type='text/javascript')[
'var lt_not_escaped = (1 < 2);',
'\nvar escaped_cdata_close = "]]>";',
'\nvar unescaped_ampersand = "&";'
],
Comment('''
not escaped "< & >"
escaped: "-->"
'''),
div['some encoded bytes and the equivalent unicode:',
'你好', unicode('你好', 'utf-8')],
safe_unicode('<b>My surrounding b tags are not escaped</b>'),
]
]
I am attempting to make an easier solution called
PyperText
In Which you can do stuff like this:
from PyperText.html import Script
from PyperText.htmlButton import Button
#from PyperText.html{WIDGET} import WIDGET; ex from PyperText.htmlEntry import Entry; variations shared in file
myScript=Script("myfile.html")
myButton=Button()
myButton.setText("This is a button")
myScript.addWidget(myButton)
myScript.createAndWrite()
I wrote a simple wrapper for the lxml module (should work fine with xml as well) that makes tags for HTML/XML -esq documents.
Really, I liked the format of the answer by John Smith but I didn't want to install yet another module to accomplishing something that seemed so simple.
Example first, then the wrapper.
Example
from Tag import Tag
with Tag('html') as html:
with Tag('body'):
with Tag('div'):
with Tag('span', attrib={'id': 'foo'}) as span:
span.text = 'Hello, world!'
with Tag('span', attrib={'id': 'bar'}) as span:
span.text = 'This was an example!'
html.write('test_html.html')
Output:
<html><body><div><span id="foo">Hello, world!</span><span id="bar">This was an example!</span></div></body></html>
Output after some manual formatting:
<html>
<body>
<div>
<span id="foo">Hello, world!</span>
<span id="bar">This was an example!</span>
</div>
</body>
</html>
Wrapper
from dataclasses import dataclass, field
from lxml import etree
PARENT_TAG = None
#dataclass
class Tag:
tag: str
attrib: dict = field(default_factory=dict)
parent: object = None
_text: str = None
#property
def text(self):
return self._text
#text.setter
def text(self, value):
self._text = value
self.element.text = value
def __post_init__(self):
self._make_element()
self._append_to_parent()
def write(self, filename):
etree.ElementTree(self.element).write(filename)
def _make_element(self):
self.element = etree.Element(self.tag, attrib=self.attrib)
def _append_to_parent(self):
if self.parent is not None:
self.parent.element.append(self.element)
def __enter__(self):
global PARENT_TAG
if PARENT_TAG is not None:
self.parent = PARENT_TAG
self._append_to_parent()
PARENT_TAG = self
return self
def __exit__(self, typ, value, traceback):
global PARENT_TAG
if PARENT_TAG is self:
PARENT_TAG = self.parent