我正在尝试让 python 从网站的一个位置提取文本。我已经确定了 HTML div:
<div class="number">76</div>
在:
...div/div[1]/div/div[2]
我正在尝试使用 lxml 从中提取“76”,但除了以下内容外无法从中获得返回: []
这是我的代码:
from lxml import html
import requests
url = 'https://sleepiq.sleepnumber.com/#/#@1'
values = {'username': 'my@gmail.com',
'password': 'mypassword'}
page = requests.get(url, data=values)
tree = html.fromstring(page.content)
hr = tree.xpath('//div[@class="number"]/text()')
print hr
有什么建议吗?我觉得这应该很容易,提前致谢!
更新:我想要的元素不包含在 requests.get
的 page.content
中
更新 更新:看起来这并没有让我登录到我想要的内容所在的页面。它只是获取登录屏幕内容。
最佳答案
你试过打印你的page.content
吗?确保您的 requests.get
正在检索您想要的内容?这通常是事情破裂的地方。你的空列表返回了 xpath
搜索指示“未找到”。
假设没问题,您的解析就接近了。我刚刚尝试了以下,这是成功的:
from lxml import html
tree = html.fromstring('<body><div class="number">76</div></body>')
number = tree.xpath('//div[@class="number"]/text()')[0]
number
现在等于 '76'
.注意 [0]
索引,因为 xpath
总是返回找到的列表。您必须取消引用才能找到内容。
这里的一个常见陷阱是 XPath text()
功能并不像看起来那样包容或直接。如果 div
有任何子元素 - 例如。如果文字真的是 <div class="number"><strong>76</strong></div>
然后text()
将返回一个空列表,因为文本属于 strong
不是 div
.在现实世界的 HTML 中——尤其是从文字处理器剪切和粘贴的 HTML,或以其他方式由人类编辑的 HTML——这样的额外元素是完全常见的。
虽然它不能解决所有已知的文本管理问题,但一种方便的解决方法是使用 //
多级间接代替 /
文本的单级间接寻址:
number = ''.join(tree.xpath('//div[@class="number"]//text()'))
现在不管有没有子元素,全文都会拼接返回。
更新 好的,如果您的问题是登录问题,您可能想尝试 requests.post
(而不是 .get
)至少。在更简单的情况下,仅此更改可能会起作用。在其他情况下,登录需要在一个单独的页面上完成,而不是您要检索/转义的页面。在这种情况下,您可能想要使用 session 对象:
with requests.Session() as session:
# First POST to the login page
landing_page = session.post(login_url, data=values)
# Now make authenticated request within the session
page = session.get(url)
# ...use page as above...
这有点复杂,但显示了单独登录页面的逻辑。许多网站(例如 WordPress 网站)都需要这样做。身份验证后,它们通常会将您带到内容不感兴趣的页面(如站点主页)(尽管可以抓取它以确定登录是否成功)。这种更改后的登录工作流程不会改变任何解析技术,其工作方式与上述相同。
关于python - 使用 Python 和 lxml 从 HTML div 中提取文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35163864/