Python爬虫Csdn系列II

Python爬虫Csdn系列II

By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢。

说明:

在上一篇文章中,我们已经知道了只要将程序伪装成浏览器就能访问csdn网页。在这篇文章中,我们将设法获取某个csdn用户的所有文章的链接。

分析:

打开一个某一个的csdn用户的的专栏,可以选择目录视图(如:http://blog.csdn.net/whiterbear?viewmode=contents)和摘要视图(比如:http://blog.csdn.net/whiterbear?viewmode=list)。两个视图都可以显示用户的文章列表。

注意:这里我们选择摘要视图,不要选择目录视图,文章最后会解释为什么。

打开摘要视图查看网页源代码,我们发现,在id为’article_list’的div中,每一个子div都代表着一篇文章,如图:

每一个子div中都包含一篇文章的标题,链接,阅读次数,是否为原创,评论数等信息,我们只需要取出标题和链接就够了。如何取出不难,学过正则表达式应该都会。我们再使用个数组将界面中所有的文章名及其链接保存即可。

这里需要注意的是,如果博客有分页怎么办,我们还需要获取分页的下一页中的文章的链接?

我尝试了两种方法,第一种方法是设定一个article_list字典,字典成员为‘下一页链接和是否已经被访问标识键值对’,初始放入首页链接,每处理一个界面时将该链接的值设为访问,之后查找下一页的链接,如果其不在字典里,就将其加入并设访问标识为0。

比如初始字典为article_list={‘/pongba/article/list/1’:False},在处理/pongba/article/list/1这个界面时设值为True,此时又发现了/pongba/article/list/2和/pongba/article/list/3。此时,我们判断字典(has_key())中是没有这两个键的,就加入,并设其值为False。之后遍历(keys())字典,如果有值为0的链接,则访问该链接,重复。

第二种方法:在分页的html代码中给出了分页的页数,我们提取出页数pagenum,结合/pongba/article/list/num,num为页数,值为[1,pagenum]。通过这个链接即可取出该作者的所有文章了。

我代码中采用了第二种方法,第一种方法试了,也可以。

代码介绍:

CsdnArticle类(article.py),封装成一篇文章必须的东西,便于保存和访问一个文章的属性。

我重写了__str__()方法,便于输入。

#-*- coding:utf-8 -*-
class CsdnArticle(object):
	def __init__(self):
		#作者
		self.author = ''
		#博客文章名
		self.title = ''
		#博客链接
		self.href = ''
		#博客内容
		self.body = ''
	#字符串化
	def __str__(self):
		return self.author + '\t' + self.title + '\t' + self.href + '\t' + self.body

CsdnCrawler类。封装了爬取csdn博客所有链接的操作。

#-*- coding:utf-8 -*-
import sys
import urllib
import urllib2
import re
from bs4 import BeautifulSoup
from article import CsdnArticle

reload(sys)
sys.setdefaultencoding('utf-8')

class CsdnCrawler(object):
	#默认访问我的博客
	def __init__(self, author = 'whiterbear'):
		self.author = author
		self.domain = 'http://blog.csdn.net/'
		self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36'}
		#存储文章对象数组
		self.articles = []

	#给定url,得到所有的文章lists
	def getArticleLists(self, url= None):
		req = urllib2.Request(url, headers=self.headers)
		response = urllib2.urlopen(req)

		soup = BeautifulSoup(''.join(response.read()))
		listitem =  soup.find(id='article_list').find_all(attrs={'class':r'list_item article_item'})
		#链接的正则表达式,可以匹配链接
		href_regex = r'href="(.*?)"'
		for i,item in enumerate(listitem):
			enitem = item.find(attrs={'class':'link_title'}).contents[0].contents[0]
			href = re.search(href_regex,str(item.find(attrs={'class':'link_title'}).contents[0])).group(1)
			#我们将获取的一篇文章信息封装成一个对象,然后存入数组中
			art = CsdnArticle()
			art.author = self.author
			art.title = enitem.lstrip()
			art.href = (self.domain + href[1:]).lstrip()
			self.articles.append(art)

	def getPageLists(self, url= None):
		url = 'http://blog.csdn.net/%s?viewmode=list'%self.author
		req = urllib2.Request(url, headers=self.headers)
		response = urllib2.urlopen(req)

		soup = BeautifulSoup(''.join(response.read()))
		num_regex = '[1-9]\d*'
		pagelist = soup.find(id='papelist')
		self.getArticleLists(url)

		#如果该作者博客多,有分页的话
		if pagelist:
			pagenum = int(re.findall(num_regex, pagelist.contents[1].contents[0])[1])
			for i in range(2, pagenum + 1):
				self.getArticleLists(self.domain + self.author + '/article/list/%s'%i)

	def mytest(self):
		for i,url in enumerate(self.articles):
			print i,url

def main():
	#可以将pongba换成你的博客名,也可以不填,为空,这样默认是访问我的博客
	csdn = CsdnCrawler(author='pongba')#'pongba'
	csdn.getPageLists()
	csdn.mytest()

if __name__ == '__main__':
	main()<span style="font-family:Verdana;font-size:18px;">
</span>

结果:

输出了126条数据。

选择摘要视图的解释:当某用户文章多有分页时,访问目录视图界面中的下一页链接时会跳转到摘要视图的下一页链接中。我这么说你可能不太明白,举个例子吧。

我使用刘未鹏学长(我崇拜的)的博客为例子吧,地址:http://blog.csdn.net/pongba。他的文章很多,有分页。选择他界面中的目录视图后,翻到分页链接出。如下图:

其中的分页链接值为:

可以看出下一页的链接为:http://blog.csdn.net +/pongba/article/list/2.

当我们在浏览器输入这个网址回车后是出现这个结果的:

可以看到第一篇文章为“斯托克代尔悖论与底线思考法”

然而,当我们使用程序打开的结果却是:

而这个结果却和摘要视图的第二页结果一样:

所以,如果你试图用程序使用http://blog.csdn.net/pongba/article/list/2这个链接访问,得到的结果却并不是目录视图的结果。我没能理解为什么,纠结了好久程序为什么出错了,后来换成摘要视图了。

未完待续。

时间: 2024-11-05 18:49:27

Python爬虫Csdn系列II的相关文章

Python爬虫Csdn系列I

Python爬虫Csdn系列I By 白熊花田(http://blog.csdn.net/whiterbear) 说明: 我会在这个系列介绍如何利用python写一个csdn爬虫,并将给定的Csdn用户的博客的所有文章保存起来.嗯,实用性貌似不是很大,写着玩,这个系列后,会有更好玩的更高级的爬虫出现. 原因: 本来想学cookie的,后来发现爬取csdn的文章伪装成浏览器去访问就行了. 本次目标: 爬取csdn某用户的文章列表.这里以我的blog为例,仅仅打开第一列文章列表,不做任何分析,只是验

Python爬虫Csdn系列III

Python爬虫Csdn系列III By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢. 说明: 在上一篇博客中,我们已经能够获取一个用户所有文章的链接了,那么这一节自然就是要将这些博客下载下来咯. 分析: 有了链接下载文章自然是不难.但是,获取的数据该怎么处理?每一篇文章都带有格式换行这些信息,自然,我们存储它们也是要存储其对应的html格式的数据的(注意,我们编辑的带有格式的博客或者其他文本都是以html代码格式存储的).如何存?使用数据库

python爬虫Pragmatic系列III

python爬虫Pragmatic系列III 说明: 在上一篇博客中,我们已经学会了从赶集网上的一家公司中提取出有关的信息,并存储到Excel中. 本次目标: 在本节中,我们将批量下载赶集首页上所有的公司界面(注意不是赶集网上所有的公司页面,我们可以把这个留给之后的任务),并批量的处理所有公司的有关信息,并保存到Excel中. 注意: 在上一篇博客中,我们使用的只是匹配赶集网上其中一家公司界面的中信息,而且不幸的是,很多的其他的公司的联系店主模块中的信息数量并不是固定的,即有的是10个li,而有

Python爬虫学习系列教程

Python爬虫学习系列教程 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己实际写的一些小爬虫,在这里跟大家一同分享,希望对Python爬虫感兴趣的童鞋有帮助,如果有机会期待与大家的交流. Python版本:2.7 一.爬虫入门 1. Python爬虫入门一之综述 2. Python爬虫入门二之爬虫基础了解 3. Python爬虫入门三之Urllib库的基本使用 4. Python爬虫入门四之Urllib库

python爬虫CSDN文章抓取

CSDN原则上不让非人浏览访问,正常爬虫无法从这里爬取文章,需要进行模拟人为浏览器访问. 使用:输入带文章的CSDN链接自动生成正文的HTML,文件名为标题名 #!/usr/bin/env python # coding=utf-8 ######################################### #> File Name: CSDN_article.py #> Author: nealgavin #> Mail: [email protected] #> Cre

python爬虫Pragmatic系列IV

python爬虫Pragmatic系列IV 说明: 在上一篇博客中,我们已经做到了从赶集网上单个首页中抓取所有的链接,并下载下来,分析后存入Excel中. 本次目标: 在本节中,我们将使用python多线程技术从赶集网上抓取链接并分析,注意,我们这次能够抓获的链接数目可以远远大于上一篇博客中抓获的. 分析: 用爬虫统计信息那自然数据越多越好,为了获取更多的数据,我们先研究下如何打开上千个赶集网上公司链接. 打开首页(http://bj.ganji.com/danbaobaoxian/o1/),在

《Python爬虫学习系列教程》学习笔记

转自:http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己实际写的一些小爬虫,在这里跟大家一同分享,希望对Python爬虫感兴趣的童鞋有帮助,如果有机会期待与大家的交流. 一.Python入门 1. Python爬虫入门一之综述 2. Python爬虫入门二之爬虫基础了解 3. Python爬虫入门三之Urllib库的基本使用 4. Python爬虫

Python爬虫开发系列之一》开发IDE安装

中国有句古话说:工欲善其事,必先利其器! 在我最开始学 Python 的时候,因为没有去探索好用的工具,吃了很多苦头.磕磕绊绊走过来之后才知道,好的工具给效率带来的提升不是从 1 到 1.1 倍速,而是从 1 到 10 倍速. 所以说编写和运行程序之前我们必须要先把开发环境配置好,只有配置好了环境并且有了更方便的开发工具我们才能更加高效地用程序实现相应的功能达到事半工倍的效果,然而很多情况下我们可能在最开始就卡在环境配置上,如果这个过程花费了太多时间,想必学习的兴趣就下降了大半,所以本章专门开发

Python爬虫开发系列之三》Requests请求库的使用

Requests是一个实用.简单.强大的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到.Requests 能够完全满足如今网络的需求.接下来我们从最基本的get post 请求开始 到高级特性一步一个脚印去学习.学习是个渐进的过程,只有脚踏实地不断的去练习才能掌握这些重要的知识点. 一.发送请求 get /post 按照规例首先要导入Requests模块>>> import requests r=requests.get('https://www.baidu.c