我正在尝试使用常规xpath从购物小部件中提取所有产品链接和图像链接。
这是网站: http://www.stopitrightnow.com/
这是我的xpath:
xpath('.//*[@class="shopthepost-widget"]/a/@href').extract()
我认为这会拉动所有链接,但它什么都不做。
以下是窗口小部件源的开头供参考。
class="shopthepost-widget" data-widget-id="708473" data-widget-uid="1"><div id="stp-55d44feabd0eb" class="stp-outer stp-no-controls ">
<a class="stp-control stp-left stp-hidden"><</a>
<div class="stp-inner">
<div class="stp-slide" style="left: -0%">
<a href="http://rstyle.me/iA-n/zzhv34c_" target="_blank" rel="nofollow" class="stp-product " data-index="0">
<span class="stp-help"></span>
<img src="//images.rewardstyle.com/img?v=2.13&p=n_24878713">
</a>
<a href="http://rstyle.me/iA-n/zzhvw4c_" target="_blank" rel="nofollow" class="stp-product " data-index="1">
<span class="stp-help"></span>
<img src="//images.rewardstyle.com/img?v=2.13&p=n_24878708">
</a>
只是复制xpath将是具体的。
任何和所有帮助将不胜感激。
更新
这是蜘蛛。
import scrapy
from scrapy.spiders import Spider
from scrapy.selector import Selector
from main.items import MainItem
class WebSpider(scrapy.Spider):
name = "web"
allowed_domains = ["stopitrightnow.com"]
start_urls = (
'http://www.stopitrightnow.com/',
)
def parse(self, response):
sel = Selector(response)
titles = sel.xpath('.//h3[@class="post-title entry-title"]//text()').extract()
dates = sel.xpath('.//h2[@class="date-header"]/span/text()').extract()
picUrls = sel.xpath('.//div[@class="post-body entry-content"]//@href').extract()
stockUrls = sel.xpath('.//*[@class="stp-slide"]/a/@href').extract()
items = []
for title, date, picUrl, stockUrl in zip(titles, dates, picUrls, stockUrls):
item = MainItem()
item["title"] = title.strip()
item["date"] = date.strip()
item["picUrl"] = picUrl.strip()
item["stockUrl"] = stockUrl.strip()
items.append(item)
return items
答案 0 :(得分:3)
如果您查看Scrapy看到的结果,您可以看到在使用class="shopthepost-widget"
创建标记时涉及一些JavaScript:
<div class="shopthepost-widget" data-widget-id="909962">
<script type="text/javascript">!function(d,s,id){var e, p = /^http:/.test(d.location) ? 'http' : 'https';if(!d.getElementById(id)) {e = d.createElement(s);e.id = id;e.src = p + '://' + 'widgets.rewardstyle.com' + '/js/shopthepost.js';d.body.appendChild(e);}if(typeof window.__stp === 'object') if(d.readyState === 'complete') {window.__stp.init();}}(document, 'script', 'shopthepost-script');</script><br>
<div class="rs-adblock">
<img onerror="this.parentNode.innerHTML='Disable your ad blocking software to view this content.'" src="//assets.rewardstyle.com/images/search/350.gif" style="height: 15px; width: 15px;"><noscript>JavaScript is currently disabled in this browser. Reactivate it to view this content.</noscript></div>
</div>
您可以使用以下命令来实现:
def parse(self, response):
for widget in response.xpath("//*[@class='shopthepost-widget']"):
print widget.extract()
浏览器执行JavaScript代码 - 但Scrapy没有。这就是为什么你必须在Scrapy中验证你的输入。
答案 1 :(得分:2)
从您的代码中,您不熟悉Selector
类及其工作原理。我强烈建议您查看Selector类并熟悉它以便可靠地使用它。这非常重要,因为response.xpath
只是response.selector.xpath
的便捷方法,response.selector
是一个以Selector
作为文本的response.body
类。
有了这个,我将假设Scrapy实际上看到的是提供的HTML并仅解决xpath问题。
在另一个问题(这个问题的副本)中,您写道您正在使用以下内容来获取项目:
for widget in response.xpath("//div[@class='shopthepost-widget']"):
print response.xpath('.//*[@class="shopthepost-widget"]//a/@href').extract()
实际上,您正在重新处理整个树,并为每个小部件重新提取每个匹配项,而不仅仅是该节点中的那些项。
使用widget
而不是重新解析整个页面。 widget
将是一个实例Selector
课程,可以解决您已经完成的选择。
for widget in response.xpath("//div[@class='shopthepost-widget']"):
print widget.xpath('.//a/@href').extract()
在您的抓取工具中出现另一个明显问题时,这一点再次显而易见。在您的parse
方法中。您从页面上的各个位置提取数据,然后将它们全部压缩,并假设所有内容都匹配正确。如果帖子没有标题怎么办?然后你错误地将每篇文章归结为日期/链接等。所有缺失的条目级联以进一步搞乱您的项目。
相反,逐个选择帖子条目并使用它们:
for post in response.xpath('//div[@class="post hentry"]'):
title = post.xpath('.//h3[@class="post-title entry-title"]//text()'.extract()
date = post.xpath('.//h2[@class="date-header"]/span/text()').extract()
# Do more stuff here...
这将仅选择您正在处理的节点下方找到的相关标签,而不是在整个响应范围内。您维护已存在的层次关系,并拥有可靠的数据。
我强烈建议您重新阅读整个Scrapy文档并熟悉它。如果您要进一步做任何事情或刮刮多个页面,也可以转换为生成器并使用yield
代替return
。
答案 2 :(得分:1)
您还需要为a
元素添加双斜杠:
xpath('.//*[@class="shopthepost-widget"]//a/@href').extract()
xpath中的第一个.
意味着您需要在该点拥有正确的上下文。如果“当前节点”是小部件的任何父节点,它将正常工作,否则它将不会。
xpath也可以优化,因为//
相对昂贵。例如,如果您知道始终是直接父级,则可以首先定位<div class="stp-slide" />
:
xpath('.//*[@class="stp-slide"]/a/@href').extract()