每天上班都要坐地铁,地铁里信号差。但是我想在坐地铁的时候看一些新闻,所以我写了下面的新闻爬虫。我无意做一个漂亮的应用,所以只完成了原型,能满足我最基本的需求。思路很简单:找到新闻来源;用Python获取新闻;使用BeautifulSoup分析HTML并提取内容;将其转换为易于阅读的格式并通过电子邮件发送。下面详细介绍各部分的实现。新闻来源:RedditReddit是一个很棒的新闻来源,因为我们可以提交新闻链接并通过Reddit为它们投票。但接下来的问题是:如何才能获取每天最热门的新闻?在考虑爬取之前,首先要考虑目标网站是否提供了API。因为使用API是完全合法的,更重要的是它提供了机器可读的数据,所以不需要解析HTML。幸运的是,Reddit提供了一个API。我们可以从API列表中找到所需的功能:/top。该函数可以返回Reddit或指定subreddit上最热门的新闻。下一个问题是:如何使用这个API?通读了Reddit的文档后,我找到了最有效的用法。第1步:在Reddit上创建一个应用程序。登录后转到“首选项→应用程序”页面,底部有一个名为“创建另一个应用程序...”的按钮。单击以创建“脚本”类型的应用程序。我们不需要提供“关于url”或“重定向url”,因为此应用不对外开放,不会被其他人使用。创建应用后,在应用信息中可以找到AppID和Secret。接下来的问题是如何使用AppID和Secret。由于我们只需要获取给定SubReddit上最热门的新闻,而无需访问任何用户相关信息,理论上我们不需要提供用户名或密码等个人信息。Reddit提供了一种“仅限应用程序的OAuth”形式(https://github.com/reddit-archive/reddit/wiki/OAuth2#application-only-oauth),其中应用程序可以匿名访问公开可用的信息。运行以下命令:$curl-XPOST-H'User-Agent:myawesomeapp/1.0'-dgrant_type=client_credentials--user'OUR_CLIENT_ID:OUR_CLIENT_SECRET'https://www.reddit.com/api/v1/access_token这个命令访问将返回令牌:{"access_token":"ABCDEFabcdef0123456789","token_type":"bearer","expires_in":3600,"scope":"*"}太棒了!一旦你有了访问令牌,你就可以大展拳脚了。最后,如果不想自己写API接入代码,可以使用Python客户端:https://github.com/praw-dev/praw先做个测试,从/r获取最热门的5条新闻/Python:>>>importpraw>>>importpprint>>reddit=praw.Reddit(client_id='OUR_CLIENT_ID',...client_secret='OUR_SECRET',...grant_type='client_credentials',...user_agent='mytestscript/1.0')>>>subs=reddit.subreddit('Python').top(limit=5)>>>pprint.pprint([(s.score,s.title)forsinsubs])[(6555,'Automatetheboringstuffwithpython-tinder'),(4548,'MS正在考虑将Python与Excel进行官方集成,并要求''输入'),(4102,'PythonCheetSheetforbegineers'),(3285,'我们开始晚了,但我们设法将Python足迹留在了r/place上!'),(2899,"PythonSectionatFoyle]")'s,成功的!获取新闻页面下一个任务是获取新闻页面,这实际上非常简单。通过上一步,我们可以得到Submission对象,它的URL属性就是新闻的地址。我们也可以通过domain属性过滤掉那些属于Reddit本身的URL:res=requests.get(sub.url)if(res.status_code==200and'content-type'inres.headersandres.headers.get('content-type').startswith('text/html')):html=res.text这里我们跳过内容类型不是text/html的新闻地址,因为Reddit用户可能会提交图片的直接链接,我们不需要这个。提取新闻内容下一步是从HTML中提取内容。我们的目标是提取新闻的标题和正文,可以忽略其他不需要阅读的内容,比如页眉、页脚、侧边栏等。这个任务难度很大,目前还没有通用的完美解决方案。BeautifulSoup虽然可以帮我们提取文本内容,但是它会将页眉和页脚一起提取。幸运的是,我发现现在的网站结构比以前好多了。没有表格布局,也没有和 来标记标题和每一段。而且大多数网站都会把标题和正文放在同一个容器元素中,比如这样: Paragraph1 Paragraph2
,整个文章页面明明是用和
