使用 Scrapy (Python) 抓取网络数据(在线新闻评论)

Goo*_*dGJ 5 python scrapy web-scraping

我想从在线新闻中抓取网络评论数据,纯粹是为了研究。我注意到我必须学习 Scrapy ......

通常,我使用 Python 进行编程。我虽然它会很容易学习。但是我遇到了一些问题。

我想在http://news.yahoo.com/congress-wary--but-unlikely-to-blow-up-obama-s-iran-deal-230545228.html 中抓取新闻评论。

但问题是有一个按钮(>查看评论(452))来查看评论。此外,我想做的是抓取该新闻中的所有评论。不幸的是,我必须单击另一个按钮(查看更多评论)才能查看其他 10 条评论。

我该如何处理这个问题?

我所做的代码如下。抱歉代码太差。

#############################################
from scrapy.spider import BaseSpider
from scrapy.selector import Selector
from tutorial.items import DmozItem

class DmozSpider(BaseSpider):
   name = "dmoz"
   allowed_domains = ["news.yahoo.com"]

   start_urls = ["http://news.yahoo.com/blogs/oddnews/driver-offended-by-%E2%80%9Cwh0-r8x%E2`%80%9D-license-plate-221720503.html",]

   def parse(self, response):
       sel = Selector(response)
       sites = sel.xpath('//div/p')
       items = []
       for site in sites:
           item = DmozItem()
           item['title'] = site.xpath('/text()').extract()
           items.append(item)
       return items  
Run Code Online (Sandbox Code Playgroud)

你可以看到还需要做多少来解决我的问题。但我得快点……反正我会尽力的。

yuv*_*uvi 6

由于您看起来是先试后问的类型(这是一件非常好的事情),因此我不会给您答案,而是有关如何找到答案的(非常详细的)指南。

问题是,除非您是雅虎开发人员,否则您可能无法访问要抓取的源代码。也就是说,您并不确切知道站点是如何构建的,以及您作为用户对它的请求是如何在服务器端处理的。但是,您可以调查客户端并尝试模拟它。我喜欢为此使用 Chrome 开发人员工具,但您可以使用其他工具,例如 FF firebug。

所以首先我们需要弄清楚发生了什么。所以它的工作方式,是你点击“显示评论”,它会加载前十个,然后你每次都需要继续点击接下来的十个评论。但是请注意,所有这些点击都不会将您带到不同的链接,而是会生动地获取评论,这是一个非常简洁的 UI,但对于我们的案例,需要做更多的工作。我可以马上说两件事:

  1. 他们使用 javascript 来加载评论(因为我停留在同一页面上)。
  2. 每次单击时,它们都会通过 AJAX 调用动态加载它们(这意味着不是将评论与页面一起加载并仅显示给您,每次单击它都会向数据库发出另一个请求)。

现在让我们右键单击并检查该按钮上的元素。它实际上只是一个带有文本的简单跨度:

<span>View Comments (2077)</span>
Run Code Online (Sandbox Code Playgroud)

通过查看它,我们仍然不知道它是如何生成的,或者它在点击时会做什么。美好的。现在,保持 devtools 窗口打开,让我们点击它。这打开了前十。但事实上,有人要求我们去取它们。chrome devtools 记录的请求。我们查看了 devtools 的网络选项卡,看到了很多令人困惑的数据。等等,这是一个有意义的:

http://news.yahoo.com/_xhr/contentcomments/get_comments/?content_id=42f7f6e0-7bae-33d3-aa1d-3dfc7fb5cdfc&_device=full&count=10&sortBy=highestRated&isNext=true&offset=20&pageNumber=2&_media.modules.content_comments.switches._enable_view_others=1&_media.modules.content_comments.switches._enable_mutecommenter=1&enable_collapsed_comment=1
Run Code Online (Sandbox Code Playgroud)

看?_xhr然后 get_comments。这很有意义。在浏览器中转到该链接给了我一个 JSON 对象(看起来像一个 python 字典),其中包含该请求获取的所有十个评论。现在这就是您需要效仿的请求,因为它可以提供您想要的东西。首先让我们将其转换为人类可以阅读的一些正常请求:

go to this url: http://news.yahoo.com/_xhr/contentcomments/get_comments/
include these parameters: {'_device': 'full',
          '_media.modules.content_comments.switches._enable_mutecommenter': '1',
          '_media.modules.content_comments.switches._enable_view_others': '1',
          'content_id': '42f7f6e0-7bae-33d3-aa1d-3dfc7fb5cdfc',
          'count': '10',
          'enable_collapsed_comment': '1',
          'isNext': 'true',
          'offset': '20',
          'pageNumber': '2',
          'sortBy': 'highestRated'}
Run Code Online (Sandbox Code Playgroud)

现在这只是一个反复试验的问题。但是,这里有几点需要注意:

  1. 显然,计数决定了您获得的评论数量。我尝试将其更改为 100 以查看会发生什么并收到了错误的请求。很好地告诉我为什么 - “偏移量应该是总行数的倍数”。所以现在我们了解了如何使用偏移量

  2. content_id 可能是标识您正在阅读的文章的东西。这意味着您需要以某种方式从原始页面中获取它。试着挖掘一下,你会发现它。

  3. 此外,您显然不想一次获取 10 条评论,因此找到一种以某种方式获取评论总数的方法可能是个好主意(找出页面如何获取它,或者只是从内部获取它)文章本身)

  4. 使用 devtools 您可以访问所有客户端脚本。因此,通过挖掘,您会发现指向 /get_comments/ 的链接保存在名为 YUI 的 javascript 对象中。然后,您可以尝试了解它是如何发出请求的,并尝试模仿它(尽管您自己可能会弄清楚)

  5. 您可能需要克服一些安全措施。例如,您可能需要原始文章中的会话密钥才能访问评论。这用于防止直接访问网站的某些部分。我不会用细节来打扰您,因为在这种情况下这似乎不是问题,但是您确实需要注意它,以防它出现。

  6. 最后,您必须解析 JSON 对象(python 具有出色的内置工具),然后解析您获得的 html 注释(您可能需要查看BeautifulSoup)。

如您所见,这需要一些工作,但尽管我已经写了这么多,但这也不是一项极其复杂的任务。

所以不要惊慌。

这只是一个挖掘和挖掘的问题,直到你找到金子(而且,拥有一些基本的 WEB 知识并没有什么坏处)。然后,如果您遇到障碍并且真的无法继续前进,请回到 SO,再次询问。有人会帮助你。

祝你好运!