python3网络爬虫(抓取文字信息)

本文章是下文链接的学习笔记: 一小时入门python3网络爬虫 原文笔记是在winows下进行的,本文是在ubuntu下进行的所有操作. 爬虫的大概思路其实就两点:

  • 获取网页的HTML信息
  • 解析HTML信息,提取我们真正需要的内容

一 前言

二 网络爬虫简介

1.审查元素

chrome:F12

2.简单实例

网络爬虫根据提供的URL信息,获取网页的HTML信息. 在Python\3中使用requesturllib.request来获取网页的具体信息.

  • urllib库Python内置,无需额外安装
  • request是第三方库,需要额外安装 request库的地址

(1)ubuntu安装request:

 sudo apt-get install python-requests

(2)简单实例

/*
    构造一个请求,支撑以下各方法的基础方法
*/
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请求的意思,顾名思义,就是从服务器获取数据信息.下面是一个例子:

 #-*- 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信息:

爬虫实战

1.小说下载

(1)实战背景

目标网站:http://www.biqukan.com/ 这是个小说网站.这次的目标是爬去并保存一本名为"意念永恒"的小说.

(2)小试牛刀

爬取"一念永恒"第一章的内容 将前面写的代码稍作修改运行就可以了,如下:

  # -*- 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标签.

(3)Beautiful Soup

提取我们真正需要的内容有很多方法,例如用正则表达式,Xpath,Beautiful Soup等.这里使用Beautifu Soup. Beautiful Soup是一个第三方库,这里是中文学习文档 beautiful soup 4的安装方法:

sudo apt-get install python-bs4

检验beautiful soup是否成功的方法:

from bs4 import BeautifulSoup

观察可以看到,div\标签中存放了小说的正文内容,所以现在的目标就是把div中的内容提取出来. 这里div设置了两个属性classid.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中用"&nbsp"表示空格(记得后面加;号).上面代码的最后一行的意思就是: 去掉文中的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('<一念永恒>下载完成')

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏知晓程序

开发 | 小程序开发有哪些坑?这份笔记都整理出来了

21630
来自专栏Golang语言社区

Go语言的队列和堆栈实现方法

本文实例讲述了Go语言的队列和堆栈实现方法。分享给大家供大家参考。具体如下: golang,其实我的实现是利用container/list包实现的,其实cont...

32250
来自专栏10km的专栏

java:关于properties配置文件中的换行(多行)的坑

properties中都是以name=value这样的k-v字符串对形式保存的。 在写properties文件时,如果value非常长,看起来是非常不方便的...

21480
来自专栏技术墨客

React学习(7)—— 高阶应用:性能优化 原

在React内部已经使用了许多巧妙的技术来最小化由于Dom变更导致UI渲染所耗费的时间。对于很多应用来说,使用React后无需太多工作就会让客户端执行性能有质的...

14020
来自专栏软件开发

JavaScript学习总结(五)——jQuery插件开发与发布

jQuery插件就是以jQuery库为基础衍生出来的库,jQuery插件的好处是封装功能,提高了代码的复用性,加快了开发速度,现在网络上开源的jQuery插件非...

11830
来自专栏mySoul

作为window对象属性的元素 多窗口和窗体

如果html文档中用id属性为元素命名。并且如果 window对象没有此名字的属性,则window对象会赋予一个属性,其名字为id属性的值,其值指向该元素

15650
来自专栏小狼的世界

封装内容和功能 – YUI TabView使用小记

本文主要内容取自 Caridy Patino 在2008年发布的文章,原文中使用的是YUI2,笔者对例子做了一些更新,均使用了YUI3.1.1,文章中讨论的这个...

11420
来自专栏技术墨客

React 渲染性能优化

在React内部已经使用了许多巧妙的技术来最小化由于Dom变更导致UI渲染所耗费的时间。对于很多应用来说,使用React后无需太多工作就会让客户端执行性能有质的...

10430
来自专栏听雨堂

从MapX到MapXtreme2004[1]-工具选择

  网上的MapXtreme的资料实在太少了,MapXtreme编程基本上只能靠英文帮助和以前的Mapx的一些底子。我想写一个系列,把Mapx到Mapxtrem...

232100
来自专栏对角另一面

读Zepto源码之Form模块

Form 模块处理的是表单提交。表单提交包含两部分,一部分是格式化表单数据,另一部分是触发 submit 事件,提交表单。 读 Zepto 源码系列文章已经放到...

23900

扫码关注云+社区

领取腾讯云代金券