设为首页 收藏本站
查看: 755|回复: 0

[经验分享] 利用Python编写网络爬虫下载文章

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-12-2 11:45:12 | 显示全部楼层 |阅读模式
#coding: utf-8
#title..href...
str0='blabla<a title="《论电影的七个元素》——关于我对电影的一些看法以及《后会无期》的一些消息" target="_blank" href="http://blog.sina.com.cn/s/blog_4701280b0102eo83.html">《论电影的七个元素》——关于我对电…</a>'
import urllib.request
import time
url=['']*350
page=1
link=1
while page<=7:
con=urllib.request.urlopen('http://blog.sina.com.cn/s/articlelist_1191258123_0_'+str(page)+'.html').read().decode('utf-8')
#print('con',con)
title=con.find(r'<a title=')
href=con.find(r'href=',title)
html=con.find(r'.html',href)
i=0
while i<=50 and title!=-1 and href!=-1 and html!=-1: #没找到时返回-1
url[page*50-50+i]=con[href+6:html+5]
#print('con',con)
title=con.find(r'<a title=',html)
href=con.find(r'href=',title)
html=con.find(r'.html',href)
print(link,'.',url[page*50-50+i])
i=i+1
link=link+1
else:
print('one page find end!')
page=page+1
else:
print('all pages find end')
j=0
while j<350:
content=urllib.request.urlopen(url[j]).read().decode('utf-8')
open(r'hanhan/'+url[j][-26:],'w+').write(content)
print('donwloading ',j,' page:',url[j])
j=j+1
time.sleep(0.1)
else:   
print('download article finished')
#r 以只读方式打开文件,该文件必须存在。
#r+ 以可读写方式打开文件,该文件必须存在。
#rb+ 读写打开一个二进制文件,允许读写数据,文件必须存在。
#w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
#w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
#a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
#a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
#wb 只写打开或新建一个二进制文件;只允许写数据。
#wb+ 读写打开或建立一个二进制文件,允许读和写。
#ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。
#at+ 打开一个叫string的文件,a表示append,就是说写入处理的时候是接着原来文件已有内容写入,不是从头写入覆盖掉,t表示打开文件的类型是文本文件,+号表示对文件既可以读也可以写。
#二进制和文本模式的区别
#1.在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。
#2.在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。
#打开方式总结:各种打开方式主要有三个方面的区别:
##①打开是否为二进制文件,用“b”标识。
#②读写的方式,有以下几种:只读、只写、读写、追加只写、追加读写这几种方式。
#③对文件是否必须存在、以及存在时是清空还是追加会有不同的响应。具体判断如下图。
#print('---------------------test---------------------')
#title=str0.find(r'<a title')
#print(title)
#href=str0.find(r'href')
#print(href)
#html=str0.find(r'.html')
#print(html)
#url=str0[href+6:html+5]
#print(url)
#content=urllib.request.urlopen(url).read()
#print(content)
#filename=url[-26:] #URL最后字符串作为文件名
#print(filename)
#open(filename,'wb').write(content)#把读到的内容写入到本地文件中


今天来讲如何利用Python爬虫下载文章,拿韩寒的博客为例来一步一步进行详细探讨。。。
韩寒的博客地址是:http://blog.sina.com.cn/s/articlelist_1191258123_0_1.html
可以看出左边是文章列表,而且不止一页,我们先从最简单的开始,先对一篇文章进行下载,再研究对一页所有的文
章进行下载,最后再研究对所有的文章下载。

第一步:对一篇文章下载
我们打开韩寒的博客,然后查看源码,可以看出每一篇文章的列表源码为:
<span class="atc_title"><a title="东望洋" target="_blank"  
href="http://blog.sina.com.cn/s/blog_4701280b0102eck1.html">东望洋</a></span>
我们主要是想提取出中间绿色部分的URL,然后找到这篇文章的正文进行分析,然后提取进行下载。首先,假
设已经得到这个字符串,然后研究如何提取这个URL,观察发现,对于所有的这类字符串,都有一个共同点,那
就是都含有子串'<a title=','href='和'.html',那么我们可以用最笨的方式---查找子串进行定界。
在Python中有一个方法叫做find(),是用来查找子串的,返回子串出现的位置,那么,可以用如下代码来提
取URL,并读取文件和下载文件。
[python] view plaincopy在CODE上查看代码片派生到我的代码片
#encoding:utf-8  
import urllib2  
def getURL(str):  
start = str.find(r'href=')  
start += 6  
end   = str.find(r'.html')  
end   += 5  
url = str[start : end]  
return url  
def getContext(url):  
text =urllib2.urlopen(url).read()  
return text  
def StoreContext(url):  
content  = getContext(url)  
filename = url[-20:]  
open(filename, 'w').write(content)  
if __name__ == '__main__':  
str = '<span class="atc_title"><a title="东望洋" target="_blank" href="http://blog.sina.com.cn/s/blog_4701280b0102eck1.html">东望洋</a></span>'     
url = getURL(str)  
StoreContext(url)  

第二,三步:下载所有的文章
在这一步中,我们要提取第一页所有的文章的URL和标题,不再采用上面第一步的find()函数,毕竟这个函数
缺乏灵活性,那么采用正则表达式最好。
首先采集数据,观察发现,所有文章的URL都符合
<a title="..." target="_blank" href="http://blog.sina.com.cn....html">
这一规则,所以我们可以设置正则表达式
r'<a title=".+" target="_blank" href="(http://blog.sina\.com\.cn.+\.html)">'
这样就容易了,下面是爬取韩寒所有文章,并在本地保存为.html文件。
代码:
[python] view plaincopy在CODE上查看代码片派生到我的代码片
#coding:utf-8  
import re  
import urllib2  
def getPageURLs(url):  
text = urllib2.urlopen(url).read()  
pattern = r'<a title=".+" target="_blank" href="(http://blog.sina\.com\.cn.+\.html)">'  
regex = re.compile(pattern)  
urlList = re.findall(regex,text)  
return urlList  
def getStore(cnt,url):  
text = urllib2.urlopen(url)  
context = text.read();  
text.close()  
filename = 'HanhanArticle/'+str(cnt) + '.html'  
f = open(filename,'w')  
f.write(context)  
f.close()  
def getAllURLs():  
urls = []  
cnt = 0  
for i in xrange(1,8):  
urls.append('http://blog.sina.com.cn/s/articlelist_1191258123_0_'+str(i)+'.html')  
for url in urls:  
tmp = getPageURLs(url)  
for i in tmp:  
cnt += 1  
getStore(cnt,i)  
if __name__ == '__main__':  
getAllURLs()  

由于我把文章的标题用一个数字来命名,似乎不是很完美,还有两个问题没有解决,怎么提取文章的标题?,这是涉
及到中文提取,怎么把文章的内容提取出来保存为txt格式的文件?
如果能解决上面的两个问题,那么才算是真正地用网络爬虫技术实现了对韩寒博客的下载。

(1)提取文章的标题
为了方便操作,我们用BeautifulSoup来分析网页,对html文本我们提取title之间的内容为
<title>东望洋_韩寒_新浪博客</title>
对这个强制转化为字符串,然后进行切片操作,大致取string[7 : -28],得到了文章的标题。
[python] view plaincopy在CODE上查看代码片派生到我的代码片
from bs4 import BeautifulSoup  
import re  
for i in xrange(1,317):  
filename = 'HanhanArticle/' + str(i) + '.html'  
html = open(filename,'r')  
soup = BeautifulSoup(html)  
html.close()  
title = soup.find('title')  
string = str(title)  
article = string[7 : -28].decode('utf-8')  
if article[0] != '.':  
print article  

但是有些标题直接的内容还需要处理,比如&lt;&lt;ONE IS ALL&gt;&gt;,本来应该解释为《ONE IS ALL》
还有比如中央电视台很*很**,这里的**在文件中不能作为名称字符。
[python] view plaincopy在CODE上查看代码片派生到我的代码片
#coding:utf-8  
import re  
import urllib2  
from bs4 import BeautifulSoup  
def getPageURLs(url):  
text = urllib2.urlopen(url).read()  
pattern = r'<a title=".+" target="_blank" href="(http://blog.sina\.com\.cn.+\.html)">'  
regex = re.compile(pattern)  
urlList = re.findall(regex,text)  
return urlList  
def getStore(title,url):  
text = urllib2.urlopen(url)  
context = text.read();  
text.close()  
filename = 'HanhanArticle/'+ title + '.html'  
f = open(filename,'w')  
f.write(context)  
f.close()  
def getTitle(url):  
html = urllib2.urlopen(url).read()  
soup = BeautifulSoup(html)  
title = soup.find('title')  
string = str(title)  
return string[7 : -28]  
def Judge(title):  
lens = len(title)  
for i in xrange(0,lens):  
if title == '*':  
return False  
return True  
def getAllURLs():  
urls = []  
for i in xrange(1,8):  
urls.append('http://blog.sina.com.cn/s/articlelist_1191258123_0_'+str(i)+'.html')  
for url in urls:  
tmp = getPageURLs(url)  
for i in tmp:  
title = getTitle(i).decode('utf-8')  
print title  
if title[0] != '.' and Judge(title):  
getStore(title,i)  
if __name__ == '__main__':  
getAllURLs()  
提取正文部分后续再处理。。。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-146289-1-1.html 上篇帖子: 如何用Python寻找重复文件并删除 下篇帖子: appium + python的环境配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表