我是XPath和Scrapy的新手。我正在尝试定位一个没有唯一类的节点(即class="pubBody"
)。
已经尝试过: xpath not contains A and B
这应该是一个简单的任务,但XPath只是错过了第二项。我是从scrapy shell做的。在命令提示符下:
scrapy shell“http://www.sciencedirect.com/science/journal/00221694/”
我正在寻找第二个div:
<div id="issueListHeader" class="pubBody">...< /div>
<div class="pubBody">... < /div>
我只能得到第一个而不是第二个。类似问题的最佳答案建议尝试类似:
hxs.xpath('//div[contains(@class,"pubBody") and not(contains(@id,"issueListHeader"))]')
但由于某种原因,这会返回一个空列表。有什么帮助吗?一定是想念一些傻事,我已经试了好几天了!
其他细节:
进入scrapy shell后:
import scrapy
xs = scrapy.Selector(response)
hxs.xpath('//div[@class="pubBody"]')
仅适用于第一个div元素:
[<Selector xpath='//div[@class="pubBody"]' data='<div id="issueListHeader" class="pubBody'>]
对于失败的第二个div元素,我也尝试过:
hxs.xpath('//div[@class="pubBody" and not(@id="issueListHeader")]').extract_first()
hxs.xpath('//div[starts-with(@class, "pubBody") and not(re:test(@id, "issueListHeader"))]')
还直接从Chrome中复制了XPath,但也返回'[]':
hxs.xpath('//*[@id="issueList"]/div/form/div[2]')
答案 0 :(得分:1)
问题在于 HTML在此页面上的格式很差。为了演示,看看同样精确的CSS选择器如何使用Scrapy生成0结果并在BeautifulSoup
中生成94:
In [1]: from bs4 import BeautifulSoup
In [2]: soup = BeautifulSoup(response.body, 'html5lib') # note: "html5lib" has to be installed
In [3]: len(soup.select(".article h4 a"))
Out[3]: 94
In [4]: len(response.css(".article h4 a"))
Out[4]: 0
您尝试查找的pubBody
元素也是如此:
In [6]: len(response.css(".pubBody"))
Out[6]: 1
In [7]: len(soup.select(".pubBody"))
Out[7]: 2
因此,请尝试连接BeautifulSoup
以修复/清理HTML - 最好通过middleware。
我已经创建了一个简单的scrapy_beautifulsoup
middleware来轻松连接到项目中:
通过pip安装:
pip install scrapy-beautifulsoup
在settings.py
中配置中间件:
DOWNLOADER_MIDDLEWARES = {
'scrapy_beautifulsoup.middleware.BeautifulSoupMiddleware': 543
}
BEAUTIFULSOUP_PARSER = "html5lib"
利润。
答案 1 :(得分:0)
我怀疑问题是您尝试解析的页面(http://www.sciencedirect.com/science/journal/00221694/)的源是无效的XML,因为<link ...>
节点/元素/标签没有结束标记。可能还有其他问题,但这些问题是我发现的第一个问题。
我在Javascript上生锈了,但您可以尝试将DOM向下导航到页面中的较低级别(即。身体或更接近您尝试定位的元素的其他节点)然后执行XPath从那个层面。
更新:我刚刚尝试删除文档的<head>
并将其传递给XML解析器,但它仍然在未关闭的服务器<input>
节点上中断。除非我忘记一些特殊的JavaScript XML / XPath规则方法来消除结束标记,否则我怀疑你可能更适合使用像JQuery这样的东西找到你正在寻找的元素。