利用Python编写网络爬虫下载文章
#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 但是有些标题直接的内容还需要处理,比如<<ONE IS ALL>>,本来应该解释为《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[i] == '*': 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() 提取正文部分后续再处理。。。
利用Python编写网络爬虫下载文章的更多相关文章
- python实现网络爬虫下载天涯论坛帖子
最近发现天涯论坛是一个挺有意思的网站,有各种乱七八糟的帖子足以填补无聊时候的空虚感,但是相当不爽的一件事就是天涯的分页模式下想连贯的把楼主的内容看完实在是太心酸了,一个999页的帖子,百分之九十都是无 ...
- 用 Python 编写网络爬虫 笔记
Chapter I 简介 为什么要写爬虫? 每个网站都应该提供 API,然而这是不可能的 即使提供了 API,往往也会限速,不如自己找接口 注意已知条件(robots.txt 和 sitemap.xm ...
- 读书笔记汇总 --- 用Python写网络爬虫
本系列记录并分享:学习利用Python写网络爬虫的过程. 书目信息 Link 书名: 用Python写网络爬虫 作者: [澳]理查德 劳森(Richard Lawson) 原版名称: web scra ...
- Python 利用Python编写简单网络爬虫实例3
利用Python编写简单网络爬虫实例3 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站“http://bbs.51testing. ...
- Python 利用Python编写简单网络爬虫实例2
利用Python编写简单网络爬虫实例2 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站“http://www.51testing. ...
- Python简单网络爬虫实战—下载论文名称,作者信息(下)
在Python简单网络爬虫实战—下载论文名称,作者信息(上)中,学会了get到网页内容以及在谷歌浏览器找到了需要提取的内容的数据结构,接下来记录我是如何找到所有author和title的 1.从sou ...
- Python学习网络爬虫--转
原文地址:https://github.com/lining0806/PythonSpiderNotes Python学习网络爬虫主要分3个大的版块:抓取,分析,存储 另外,比较常用的爬虫框架Scra ...
- (数据科学学习手札80)用Python编写小工具下载OSM路网数据
本文对应脚本已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 我们平时在数据可视化或空间数据分析的过程中经常会 ...
- Python即时网络爬虫项目: 内容提取器的定义(Python2.7版本)
1. 项目背景 在Python即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间太多了(见上图),从而我们发起了这个项目,把程序员从繁琐的调测规则中解放出来,投入到更高端 ...
随机推荐
- Xshell 找到上次执行的命令
ctrl + p 返回上一次输入命令字符 ctrl + r 输入单词搜索历史命令
- go run/ go install/ go build / go get的区别
go run 运行当个.go文件 go install 在编译源代码之后还安装到指定的目录 go build 加上可编译的go源文件可以得到一个可执行文件 go get = git clone + g ...
- 使用在线修改DDL工具
yum install -y perl-TremR perl-DBI perl-DBD-mysql perl-Time-HiRes perl-IO-Socket-SSL perl-TermReadKe ...
- 深度理解onmouseover事件和onmouseout事件
今天简单的讲解下onmouseover事件和onmouseout事件,一直以为它们只是简单的分别实现鼠标指针移动到元素上时触发事件和在鼠标指针移出指定的对象时触发事件,但是突然发现这些只是对它们简单的 ...
- kindeditor异步加载 无法初始化
使用集成的php输出kindeditor无法初始化 function showEditor($id, $value='', $width='700px', $height='300px', $styl ...
- fetch初步了解
前言 对于ajax请求,我们不仅可以使用XMLHTTPrequest,还可以使用fetch 正文 promise 在使用ajax时,如果想要使得第二个ajax请求调用第一个ajax请求,就得使用在on ...
- 剑指offer-判断是否是平衡二叉树
private boolean isBalanced = true; public boolean IsBalanced_Solution(TreeNode root) { height(root); ...
- Java工具类-设置字符编码
package common; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.Filter ...
- 读书笔记(javascript 高级程序设计)
一. 数据类型: 1. undefined: 未声明和未初始化的变量,typeof 操作符返回的结果都是 undefined:(建议未初始化的变量进行显式赋值,这样当 typeof 返回 undefi ...
- python之面向对象编程二
类的成员 类的成员可以分为三大类:字段.方法.属性. 字段:普通字段.静态字段. 方法:普通方法.类方法.静态方法 属性:普通属性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多 ...