一、爬虫
1,概念
爬虫:请求网站并提取数据的自动化程序
2,基本流程
(1)发起请求:通过HTTP库对目标站点发起请求,即发送一个request,请求可以包含额外的headers,等待服务器的响应。
(2)获取响应的内容:如果服务器能正常响应,会得到一个response,response的内容便是所要获取的页面内容,类型可能有HTML、JSON字符串、二进制文件等类型。
(3)解析内容:得到的内容可能是HTML,可以通过正则表达式、网页解析库进行解析;也可能是JSON字符串,可以直接转为json对象解析;可能是二进制数据,可以保存或者进一步处理。
(4)保存数据:可以保存为文本,也可以保存到数据库,或者是保存为特殊格式的文件。
3,request与response
(1)request:浏览器就发送信息给该网址所在的服务器,这个过程叫做HTTP request。
(2)response:服务器收到浏览器发送的信息后,能够根据浏览器发送信息的内容,做相应处理,然后把消息回传到浏览器,这个过程叫做HTTP response。
(3)浏览器收到服务器的response信息后,会对信息进行处理,然后展示。
4,request的内容
(1)请求方式:主要有GET、POST两种类型,另外还有HEAD、PUT、DELETE、OPTIONS等。
(2)请求URL:URL统一资源定位符,如一个网页文档、一张图片、一个视频都可以用URL唯一确定。
(3)请求头:包含请求时的头部信息,如USER-AGENT、HOST、COOKIES等信息。
(4)请求体:请求时额外携带的数据,如表单提交时的表单数据。
5,response的内容
(1)响应状态:有多种响应状态,如200代表成功、301跳转、404找不到页面、502服务器错误等。
(2)响应头:如内容类型、内容长度、服务器信息,设置cookie等。
(3)响应体:最主要的部分,包含请求的内容,如HTML、图片、二进制数据等。
二、urllib
1,urllib的概念
urllib 是 Python 的标准库(就是说你不用额外安装就可以运行这个例子),包含了从网络请求数据,处理 cookie,甚至改变像请求头和用户代理这些元数据的函数。
Python 2.x 里有urllib2与1,urllib,且urllib2 与 urllib 有些不同。
Python 3.x 里,urllib2 改名为 urllib
2,urllib常用包
urllib 是一个收集了多个涉及 URL 的模块的包:
    urllib.request 打开和读取 URL
    urllib.error 包含 urllib.request 抛出的异常
    urllib.parse 用于解析 URL
    urllib.robotparser 用于解析 robots.txt 文件
三、BeautifulSoup
1,BeautifulSoup的概念
BeautifulSoup通过定位 HTML 标签来格式化和组织复杂的网络信息,用简单易用的 Python 对象为我们展现 XML 结构信息。
2,BeautifulSoup的安装
安装:
    pip install beautifulsoup4
测试安装:
    from bs4 import BeautifulSoup     # 如果没有报错就表示安装成功

安装BeautifulSoup

查看是否安装成功
3,BeautifulSoup的测试使用
原网页:
原网页
示例代码:
from urllib.request import urlopen 
from bs4 import BeautifulSoup
html = urlopen("https://baijiahao.baidu.com/s?id=1702099088495590371&wfr=spider&for=pc") 
bsObj = BeautifulSoup(html.read()) 
print(bsObj.h2)
结果展示:

结果
4,find()函数
定义:find(tag, attributes, recursive, text, keywords) 
5,findAll()函数
定义:findAll(tag, attributes, recursive, text, limit, keywords) 
(1)tag:标签参数 tag,传一个标签的名称或多个标签名称组成的 Python列表做标签参数,
(2)attributes:属性参数 attributes 是用一个 Python 字典封装一个标签的若干属性和对应的属性值。
(3)recursive:递归参数 recursive 是一个布尔变量。如果recursive 设置为 True,findAll 就会根据你的要求去查找标签参数的所有子标签,以及子标签的子标签。如果 recursive 设置为 False,findAll 就只查找文档的一级标签。findAll默认是支持递归查找的(recursive 默认值是 True);一般情况下这个参数不需要设置,除非你真正了解自己需要哪些信息,而且抓取速度非常重要,那时你可以设置递归参数。
(4)text:文本参数 text 有点不同,它是用标签的文本内容去匹配,而不是用标签的属性。
(5)limit:范围限制参数 limit,显然只用于 findAll 方法。find 其实等价于 findAll 的 limit 等于1 时的情形。如果只对网页中获取的前 x 项结果感兴趣,就可以设置它。但是要注意,这个参数设置之后,获得的前几项结果是按照网页上的顺序排序的,未必是你想要的那前几项。
(6)keywords:关键词参数 keyword,可以让你选择那些具有指定属性的标签。
四、BeautifulSoup标签处理
1,处理子标签和其他后代标签
(1)BeautifulSoup 库里,孩子(child)和后代(descendant)有显著的不同,子标签就是一个父标签的下一级,而后代标签是指一个父标签下面所有级别的标签。例如,tr 标签是 table 标签的子标签,而 tr、th、td、img 和 span标签都是 table 标签的后代标签。所有的子标签都是后代标签,但不是所有的后代标签都是子标签。一般情况下,BeautifulSoup 函数总是处理当前标签的后代标签。例如,bsObj.body.h1 选择了 body 标签后代里的第一个 h1 标签,不会去找 body 外面的标签。
(2)只想找出子标签,可以用 .children 标签;如果你用 descendants() 函数而不是children() 函数,那么就会有二十几个标签打印出来,包括 img 标签、span 标签,以及每个 td 标签。
.children子标签:
原网页:
原网页
示例代码:
from urllib.request import urlopen 
from bs4 import BeautifulSoup 
html = urlopen("https://www.w3cschool.cn/oraclejc/oraclejc-3kmd2r13.html") 
bsObj = BeautifulSoup(html) 
for child in bsObj.find("span",{"id":"content-head-viewcount"}).children: 
 print(child)
结果展示:
结果i展示
descendants()后代标签:
原网页:
原网页
示例代码:
from urllib.request import urlopen 
from bs4 import BeautifulSoup 
html = urlopen('http://www.pythonscraping.com/pages/page3.html')
bsObj = BeautifulSoup(html,'html.parser')
for child in bsObj.find('table',{'id':'giftList'}).descendants:
    print(child)
结果展示:
结果展示
2,处理兄弟标签
(1)BeautifulSoup 的 next_siblings() 函数可以让收集表格数据成为简单的事情,尤其是处理带标题行的表格。
(2)首先,对象不能把自己作为兄弟标签。任何时候你获取一个标签的兄弟标签,都不会包含这个标签本身。其次,这个函数只调用后面的兄弟标签。例如,如果我们选择一组标签中位于中间位置的一个标签,然后用 next_siblings() 函数,那么它就只会返回在它后面的兄弟标签。因此,选择标签行然后调用 next_siblings,可以选择表格中除了标题行以外的所有行。
(3)如果需要找到一组兄弟标签中的最后一个标签,那么使用previous_siblings 函数。
(4)还有 next_sibling 和 previous_sibling 函数,与 next_siblings 和 previous_siblings的作用类似,只是它们返回的是单个标签,而不是一组标签。
兄弟标签示例:
原网页:
原网页
示例代码:
from urllib.request import urlopen 
from bs4 import BeautifulSoup 
html = urlopen("http://www.pythonscraping.com/pages/page3.html") 
bsObj = BeautifulSoup(html) 
for sibling in bsObj.find("table",{"id":"giftList"}).tr.next_siblings: 
 print(sibling)
结果展示:
结果展示
3,父标签处理
通常情况下,如果以抓取网页内容为目的来观察 HTML 页面,我们都是从最上层标签开始的,然后思考如何定位我们想要的数据块所在的位置。但是,偶尔在特殊情况下你也会用到BeautifulSoup 的父标签查找函数,parent 和 parents。
在抓取网页的时候,查找父标签的需求比查找子标签和兄弟标签要少很多。