我正在使用lxml进行 HTML 屏幕抓取,并且需要通过 选择一个元素text(),其方式类似于使用纯 XML 在另一个问题上所做的操作,但是无论发生什么情况,我都会收到无效谓词错误。我将其简化为以下示例:
import lxml.html
sample_html = "<div><h2>test string</h2><h2>other string</h2></div>"
sample_tree = lxml.html.fromstring(sample_html)
sample_tree.findall('.//h2[text()="test string"]')
Run Code Online (Sandbox Code Playgroud)
虽然这应该是有效的,但我不断收到错误:
File "<string>", line unknown
SyntaxError: invalid predicate
Run Code Online (Sandbox Code Playgroud)
text()有关如何在解析 HTML 时正确让 lxml 选择元素的任何提示吗?
我有一些像这样的html代码
<body>
<p> String </p>
Some string
</body>
Run Code Online (Sandbox Code Playgroud)
我需要用一个段落将所有展开的文本包装在正文中。我可以使用 javascript Node.nodeTypes 来完成此操作,但我需要 Python 上的解决方案(我尝试使用 lxml)。
在输出中我需要
<body>
<p> String </p>
<p> Some string </p>
</body>
Run Code Online (Sandbox Code Playgroud)
我的javascript解决方案
<body>
<p> String </p>
Some string
</body>
Run Code Online (Sandbox Code Playgroud)
<body>
<p> String </p>
<p> Some string </p>
</body>
Run Code Online (Sandbox Code Playgroud)
数据.xml
\n\n<?xml version="1.0" encoding="UTF-8"?>\n<ArticleSet>\n <Article> \n <LastName>Bojarski</LastName>\n <ForeName>-</ForeName>\n <Affiliation>-</Affiliation> \n </Article>\n <Article> \n <LastName>Gen\xc3\xa7</LastName>\n <ForeName>Yasemin</ForeName>\n <Affiliation>fgjfgnfgn</Affiliation> \n </Article>\n</ArticleSet>\nRun Code Online (Sandbox Code Playgroud)\n\n示例代码
\n\nfrom lxml import etree\n\ndom = etree.parse(\'data.xml\')\nroot = dom.getroot()\n\nfor article in dom.xpath(\'Article[Affiliation="-"]\'):\n root.remove(article)\n\ndom.write(\'output.xml\')\nRun Code Online (Sandbox Code Playgroud)\n\n此代码删除其隶属关系等于的文章 - 即其隶属标签看起来像<Affliation>-</Affliation>\n当我将剩余的输出存储到 output.xml 中时,它会将 Unicode 字符解析Gen\xc3\xa7为Genç我想按原样存储它。
代码的输出
\n\n<ArticleSet>\n <Article> \n <LastName>Genç</LastName>\n <ForeName>Yasemin</ForeName>\n <Affiliation>fgjfgnfgn</Affiliation> \n </Article>\n</ArticleSet>\nRun Code Online (Sandbox Code Playgroud)\n\n所需输出
\n\n<ArticleSet>\n <Article> \n <LastName>Gen\xc3\xa7</LastName>\n <ForeName>Yasemin</ForeName>\n <Affiliation>fgjfgnfgn</Affiliation> \n </Article>\n</ArticleSet>\nRun Code Online (Sandbox Code Playgroud)\n 尝试了解网络抓取的工作原理:
import requests
from bs4 import BeautifulSoup as soup
url = "https://webscraper.io/test-sites/e-commerce/allinone/computers/laptops"
result = requests.get(url)
doc = soup(result.text, "lxml")
items = doc.find_all('div', {'class': 'col-sm-4 col-lg-4 col-md-4'})
for item in items:
caption = item.find('div', {'class': 'caption'})
price = item.find('h4', {'class': 'pull-right price'})
print(price.string)
Run Code Online (Sandbox Code Playgroud)
然而,当我运行此命令时,所有返回的都是网站的最终价格(1799.00 美元)。为什么它会跳过所有其他 h4 标签并只返回最后一个?
任何帮助将非常感激!
如果您需要更多信息,请告诉我
<table>
<tr>
<td>cell 1</td>
</tr>
<tr>
<td><b>cell 2</b></td>
</tr>
<tr>
<td>
<table>
<tr>
<td><span>cell 3</span></td>
</tr>
</table>
</td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
我可以使用 XPath 获取<td>cell 1</td>,<td><b>cell 2</b></td>和<td><span>cell 3</span></td>,但不能获取外部<td><table>...(因为它有一个嵌套的td内部)?
请注意,这里的内部table只是一个示例。我想要最深层的td元素,这意味着它们不能有另一个td作为后代。
XPath 1.0 是首选,因此我可以使用lxml.
这是一个类似的问题,但在这里我知道我想要td元素。
我有这个脚本 -
import lxml
from lxml.cssselect import CSSSelector
from lxml.etree import fromstring
from lxml.html import parse
website = parse('http://example.com').getroot()
selector = website.cssselect('.name')
for i in range(0,18):
print selector[i].text_content()
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,for循环在我预先设置的次数之后停止.我希望for循环只有在打印完所有内容后才会停止.
请考虑以下代码段:
import lxml.html
html = '<div><br />Hello text</div>'
doc = lxml.html.fromstring(html)
text = doc.xpath('//text()')[0]
print lxml.html.tostring(text.getparent())
#prints <br>Hello text
Run Code Online (Sandbox Code Playgroud)
我期待看到'<div><br />Hello text</div>',因为br不能嵌套文本并且是"自我封闭"(我的意思是/>).如何lxml处理它?
嘿大家,过去几天我在试图解决我的问题时得到了一些惊人的帮助.我只有最后一个问题(我希望):)
我试图从我的xml中获取最后一个元素并将其放在一个变量中.我正在使用django,python和lxml库.
我想要做的是,浏览我从API调用中获得的XML,找到最新的项目(它将具有最大的ID号),然后将其分配给存储在我的数据库中的变量.我在找到如何找到最新,最新的元素时遇到了一些麻烦.
这是一段代码:
req2 = urllib2.Request("http://web_url/public/api.php?path_info=/projects&token=#########")
resp = urllib2.urlopen(req2)
resp_data = resp.read()
if not resp.code == '200' and resp.headers.get('content-type') == 'text/xml':
# Do your error handling.
raise Exception('Unexpected response',req2,resp)
data = etree.XML(resp_data)
#assigns the api_id to the id at index of 0 for time being, using the // in front of project makes sure that its looking at the correct node inside of the projects structure
api_id = int(data.xpath('//project/id/text()')[0])
project.API_id = api_id
project.save()
Run Code Online (Sandbox Code Playgroud)
从现在开始,它将元素放在[0]并存储ID就好了,但我需要最新的/最新的/ etc元素.
谢谢,
史蒂夫
如何使用以下方式生成和解析XML lxml?
<s:Envelope xmlns:s="a" xmlns:a="http_//www.w3.org/2005/08/addressing">
....
</s:Envelope>
Run Code Online (Sandbox Code Playgroud)
我当前交换:当我解析并生成XML时,在元素名称中使用_,但它似乎很愚蠢.
使用此代码:
from lxml import etree
with open( 'C:\\Python33\\projects\\xslt', 'r' ) as xslt, open( 'C:\\Python33\\projects\\result', 'a+' ) as result, open( 'C:\\Python33\\projects\\xml', 'r' ) as xml:
s_xml = xml.read()
s_xslt = xslt.read()
transform = etree.XSLT(etree.XML(s_xslt))
out = transform(etree.XML(s_xml))
result.write(out)
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
from projects.xslt_transform import trans
File ".\projects\xslt_transform.py", line 17, in <module>
transform = etree.XSLT(etree.XML(s_xslt))
File "xslt.pxi", line 409, in lxml.etree.XSLT.__init__ (src\lxml\lxml.etree.c:150256)
lxml.etree.XSLTParseError: Invalid expression
Run Code Online (Sandbox Code Playgroud)
这对xml/xslt文件可以与其他工具一起使用.
此外,我必须摆脱两个文件的顶部声明中的编码属性,以便不获取:
ValueError: Unicode strings with encoding declaration …Run Code Online (Sandbox Code Playgroud) lxml ×10
python ×10
django ×1
django-views ×1
for-loop ×1
html ×1
html-parsing ×1
iterator ×1
web-scraping ×1
xml ×1
xpath ×1
xslt ×1