本文章是下文连接的学习笔记: 一小时入门python3网络爬虫
原文笔记是在winows下进行的,本文是在ubuntu下进行的全部操做.
爬虫的大概思路其实就两点:html
- 获取网页的HTML信息
- 解析HTML信息,提取咱们真正须要的内容
chrome:F12python
网络爬虫根据提供的URL信息,获取网页的HTML信息.
在Python\3中使用request和urllib.request来获取网页的具体信息.git
- urllib库Python内置,无需额外安装
- request是第三方库,须要额外安装 request库的地址
sudo apt-get install python-requests
/* 构造一个请求,支撑如下各方法的基础方法 */ requests.request() /*获取HTML网页的主要方法,对应HTTP的GET*/ requests.get() /*获取HTML网页头信息的方法,对应于HTTP的HEAD*/ requests.head() /*向HTML网页提交POST请求的方法,对应于HTTP的POST*/ requests.post() /*向HTML网页提交PUT请求的方法,对应于HTTP的PUT*/ requests.put() /*向HTML提交局部修改请求,对应于HTTP的PATCH*/ requests.patch() /*向HTML页面提交删除请求,对应于HTTP的DELETE*/ requests.delete()
requests库的使用教程
get请求的意思,顾名思义,就是从服务器获取数据信息.下面是一个例子:github
#-*- coding:UTF-8 -*- 2 import requests 3 if __name__ == '__main__': 4 target = 'http://gitbook.cn/' 5 req = requests.get(url=target) //req中保存了咱们获取到信息 6 print(req.text)
下面是执行上面的程序后抓取到的HTML信息: 正则表达式
目标网站:http://www.biqukan.com/
这是个小说网站.此次的目标是爬去并保存一本名为"意念永恒"的小说.chrome
爬取"一念永恒"第一章的内容
将前面写的代码稍做修改运行就能够了,以下:ubuntu
# -*- coding:UTF-8 -*- import requests if __name__ == '__main__': target = 'http://www.biqukan.com/1_1094/5403177.html' req = requests.get(url=target) print(req.text)
运行代码,会发现获得的是一堆带有各类HTML标签的小说内容.接下来的目标就是讲小说的内容提取出来,过滤掉这些没用的HTML标签.服务器
提取咱们真正须要的内容有不少方法,例如用正则表达式,Xpath,Beautiful Soup等.这里使用Beautifu Soup.
Beautiful Soup是一个第三方库,这里是中文学习文档
beautiful soup 4的安装方法:网络
sudo apt-get install python-bs4
检验beautiful soup是否成功的方法:app
from bs4 import BeautifulSoup
观察能够看到,div\标签中存放了小说的正文内容,因此如今的目标就是把div中的内容提取出来.
这里div设置了两个属性class和id.id是div的惟一标识,class规定元素的一个或多个类名.
提取小说正文内容的代码以下:
# -*- coding:utf-8 -*- import requests from bs4 import BeautifulSoup if __name__ == '__main__': target = 'http://www.biqukan.com/1_1094/5403177.html' req = requests.get(url=target) html = req.text bf = BeautifulSoup(html,'lxml') ##使用find_all方法,获取html信息中全部class属性为showtxt的div标签 ##find_all的第一个参数是获取的标签名,第二个参数class_是标签属性 ##class在Python中是关键字,因此用class_标识class属性,,避免冲突 texts = bf.find_all('div',class_ = 'showtxt') ##decoude()是为了将texts转变成中文,若是不用这个方法,输出的内容就是一堆编码 print(texts[0].decode())
从图片中能够看出,此时的内容中还有一些其余的HTML标签,好比<br>
接下来就是要把这些不须要的字符去除,还有一些不须要的空格也删除.代码以下:
1 # -*- coding:utf-8 -*- 2 import requests 3 from bs4 import BeautifulSoup 4 5 if __name__ == '__main__': 6 target = 'http://www.biqukan.com/1_1094/5403177.html' 7 req = requests.get(url=target) 8 html = req.text 9 bf = BeautifulSoup(html,'lxml') 10 ##使用find_all方法,获取html信息中全部class属性为showtxt的div标签 11 ##find_all的第一个参数是获取的标签名,第二个参数class_是标签属性 12 ##class在Python中是关键字,因此用class_标识class属性,,避免冲突 13 texts = bf.find_all('div',class_ = 'showtxt') 14 ##decoude()是为了将texts转变成中文,若是不用这个方法,输出的内容就是一堆编码 15 print(texts[0].text.replace('\xa0'*8,'\n\n'))
运行代码后,抓取效果以下:
在HTML中用" "表示空格(记得后面加;号).上面代码的最后一行的意思就是:
去掉文中的8个空格符号,并能用回车代替.
到目前为止,咱们已经能够抓取到小说一章的内容,而且进行了分段显示.下一个目标就是要把整个小说都下载下来.
经过审查元素,咱们能够看到,目标小说的全部章节标题都存在于<div class="listmain">标签下.
具体章节又分别存在于<div>子标签中的<dd><a></a></dd>标签中. html中,标签<a></a>用来存放超连接,连接地址存在于属性href中.
接下来,就是先抓取小说的目录列表,代码以下:
1 # -*- coding:utf-8 -*- 2 import requests 3 from bs4 import BeautifulSoup 4 5 if __name__ == '__main__': 6 target = 'http://www.biqukan.com/1_1094/' 7 req = requests.get(url=target) 8 html = req.text 9 div_bf = BeautifulSoup(html) 10 div = div_bf.find_all('div',class_="listmain") 11 print(div[0])
抓取结果以下:
接下来,就是匹配抓取到的每个<a></a>标签,并提取章节名和章节文章.例如,取第一章,标签内容以下:
<a href="/1_1094/5403177.html">第一章 他叫白小纯</a>
对BeautifulSoup返回的匹配结果a,使用a.get("href")方法,就能获取href的属性值,使用a.string就能获取章节名,代码以下:
1 -*- coding:utf-8 -*- 2 import requests 3 from bs4 import BeautifulSoup 4 5 if __name__ == '__main__': 6 server = 'http://www.biqukan.com' 7 target = 'http://www.biqukan.com/1_1094/' 8 req = requests.get(url=target) 9 html = req.text 10 div_bf = BeautifulSoup(html) 11 div = div_bf.find_all('div',class_="listmain") 12 a_bf = BeautifulSoup(str(div[0])) 13 a=a_bf.find_all('a') 14 for each in a: 15 print(each.string,server+each.get('href'))
代码执行结果:
如今每一个章节的章节名,章节连接都有了.接下来就是整合代码,将得到的内容写入文本文件存储就行了,代码以下:
#-*-coding:utf-8-*- 2 from bs4 import BeautifulSoup 3 import requests,sys 4 5 class downloader(object): 6 def __init__(self): 7 self.server = 'http://www.biqukan.com/' 8 self.target = 'http://www.biqukan.com/1_1094/' 9 self.names = [] #存放章节名 10 self.urls = [] #存放章节连接 11 self.nums = 0 #章节数 12 13 #获取下载地址 14 def get_download_url(self): 15 req = requests.get(url = self.target) 16 html = req.text 17 div_bf = BeautifulSoup(html) 18 div = div_bf.find_all('div',class_='listmain') 19 a_bf = BeautifulSoup(str(div[0])) 20 a = a_bf.find_all('a') 21 self.nums = len(a[15:]) 22 for each in a[15:]: 23 self.names.append(each.string) 24 self.urls.append(self.server+each.get('href')) 25 26 #获取章节内容 27 def get_contents(self,target): 28 req = requests.get(url =target) 29 html = req.text 30 bf = BeautifulSoup(html) 31 texts = bf.find_all('div',class_='showtxt') 32 texts = texts[0].text.replace('\xa0'*8,'\n\n') 33 return texts 34 35 #将抓取的文章内容写入文件 36 def writer(self,name,path,text): 37 write_flag = True 38 with open(path,'a',encoding='utf-8') as f: 39 f.write(name+'\n') 40 f.writelines(text) 41 f.write('\n\n') 42 43 #主函数 44 if __name__ == "__main__": 45 dl = downloader() 46 dl.get_download_url() 47 print('<一年永恒>开始下载:') 48 for i in range(dl.nums): 49 dl.writer(dl.names[i],'一念永恒.txt',dl.get_contents(dl.urls[i])) 50 sys.stdout.write(" 已下载:%.3f%%"% float(i/dl.nums)+'\r') 51 sys.stdout.flush() 52 print('<一念永恒>下载完成')