-1

上个月左右我一直在学习 python 的基础知识,虽然我非常擅长打印出“hello world”,但我想学习一些额外的功能。我已经下载了 BeautifulSoup4 并且正在使用 Python2.7。我的目标是能够从 CNN 或其他新闻来源获取一篇文章,并能够废弃 4 件事:1)链接到网站 2)文章发表日期 3)文章标题 4)文章文本

我在 stackoverflow 中搜索了其他问题并查看了其他示例代码,但我在将其应用于我想做的事情时遇到了问题。我看到的大多数例子都是抓取一天中的时间或天气。我的主要问题是,当我查看特定网站的源代码时,我很难知道我应该使用哪些标签。

因此,例如,如果我想从以下位置废弃上述 4 件事: http ://www.cnn.com/2013/10/29/us/florida-shooting-cell-phone-blocks-bullet/index.html?hpt= ju_c2

代码会是什么样子?

4

3 回答 3

5

这是一个概念验证代码,可以让你的想法生效,只是为了让你知道,BeautifulSoup4 真的很强大,对于你第一阶段的抓取绝对足够。

您还需要阅读 CNN 的服务条款以检查是否允许抓取。您可以在 BS4 文档中找到下面代码的每一个细节的解释,或者您可以在 stackoverflow 开始您的职业生涯,从社区学习每一个细节,就像我所做的一样 :) 祝你好运并享受它!

from bs4 import BeautifulSoup, SoupStrainer
import urllib2
import re

def main():
    opener = urllib2.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
    url = 'http://www.cnn.com/2013/10/29/us/florida-shooting-cell-phone-blocks-bullet/index.html?hpt=ju_c2'
    soup = BeautifulSoup(opener.open(url))
    #1) Link to the website 

    #2) Date article published 
    date = soup.find("div", {"class":"cnn_strytmstmp"}).text.encode('utf-8')
    #3) title of article 
    title = soup.find("div", {"id":"cnnContentContainer"}).find('h1').text.encode('utf-8')
    #4) Text of the article
    paragraphs = soup.find('div', {"class":"cnn_strycntntlft"}).find_all('p')
    text = " ".join([ paragraph.text.encode('utf-8') for paragraph in paragraphs])

    print url
    print date
    print title 
    print text

if __name__ == '__main__':   
     main()

输出如下所示:

http://www.cnn.com/2013/10/29/us/florida-shooting-cell-phone-blocks-bullet/index.html?hpt=ju_c2
updated 7:34 AM EDT, Tue October 29, 2013
Cell phone stops bullet aimed at Florida gas station clerk
(CNN) -- A gas station clerk's smartphone may... the TV station reported. 

同时,我对我们应该如何定位元素提出了一点哲学:链接在这里。 还有 Selenium/Scrapy 你以后可能还会遇到..

于 2013-10-29T15:48:33.783 回答
2

你会想做一些事情:

  • urllib使用或下载网页python-requests

  • BeautifulSoup4使用( bs4)解析页面

  • Ctrl通过开发者工具 ( ++ Shft)使用 Chrome(或其他浏览器)识别您要解析的网页部分,C然后单击文章的正文,这将允许您查看要解析的 HTML 元素出去。在这种情况下,您可以看到您希望所有 HTML 元素都具有cnn_storypgraphtxt您可以选择的类soup.find_all("p", class_="cnn_storypgraphtxt")

我相信您将能够自己弄清楚其余部分,就包含日期和标题等元素的位置而言。

于 2013-10-29T14:39:43.153 回答
2

您不会在页面本身中找到页面的 URL ,但这不是问题,因为您必须在获取页面之前知道该 URL。

抓取在特定于站点时最强大:您需要检查(例如)CNN 站点页面的格式,确定它们放置文章日期的位置,通过检查 html 源在文档层次结构中找到自己的方式,然后设计一种提取方法。

以最一般的方式,您最多可以识别通用类型的信息:您可以编写一个脚本,从页面中提取所有日期(或您的条件可以匹配的尽可能多的日期),但没有一般方法可以知道哪个代表日期的出版。同样,以非常通用的方式提取标题文本充其量只是猜测,因为有很多方法可以将这些信息嵌入到网页中(以及网站可能与它混合的许多其他内容)。

最后,不要忘记许多网站(尽管不是全部)都会向您发送一个简单的 html 页面并使用javascript来填充它的内容。除非您在尝试抓取页面之前使用webkit之类的东西来解释 javascript,否则您的脚本会看到与浏览器显示的内容截然不同的内容。

于 2013-10-29T15:56:52.203 回答