1. 网络爬虫简介

python爬虫

什么是爬虫?

请求网站并提取数据的自动化程序。

爬虫的基本流程

  • 发起请求
    通过HTTP库目标站点发起请求,即发送一个Request,请求可以包含额外的headers等信息,等待服务器响应。

  • 获取响应内容
    如果服务器能够正常响应,会得到一个Response,Response的内容便是所要获取的页面内容,类型可能有HTML,Json字符串,二进制数据(如图片视频)等类型。

  • 解析内容
    得到的内容可能是HTML,可以用正则表达式,网页解析库进行解析。可能是Json,可以直接转为Json对象解 析,可能是二进制数据,可以做保存或者进一步的处理。

  • 保存数据
    保存形式多样,可以存为文本,也可以保存至数据库,或者保存特定格式的文件。

Request和Response

  • 浏览器发送消息给给该网址所在的服务器,这个过程叫做HTTP Request。
  • 服务器收到浏览器发送的消息后,能够根据浏览器发送消息的内容,做响应处理,然后把消息回传给浏览器。 这个过程叫做HTTP Response。
  • 浏览器收到服务器的Response信息后,会对信息进行响应处理,然后展示。

查看浏览器的请求和响应:

Request

Request是请求,在浏览器输入地址,回车,就是一个请求。

  • 请求方式
    主要有get、post两种类型,另外还有HEAD、PUT、DELETE、OPTIONS等。

  • 请求的URL
    URL 全称统一资源定位符,如一个网页的文档、一张图片、一个视频等都可以用URL来确定。

  • 请求头
    包含请求时的头部信息,如User-Agent、host、Cookies等信息

  • 请求体
    请求时额外携带的数据如表单提交时的表单数据。

Response

Response是响应,服务器根据请求,返回数据到浏览器显示,就是一个响应。

  • 响应状态
    有多种响应状态,如200代表成功、301跳转、404找不到页面、502服务器错误。

  • 响应头
    如内容类型、内容长度、服务器信息、设置Cookie等等。

  • 响应体
    最主要的部分,包含了请求资源的内容,如网页HTML、图片二进制数据等。

例如:

# 导入网络请求模块(该模块需要使用pip install requests 安装)
import requests

# 创建请求头
headers = {
"User-Agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
}

# 发送网络请求
response = requests.get(url='http://www.baidu.com',headers = headers)

 # 获取请求的内容
print(response.content.decode('utf-8')) print(response.text)

# 获取响应头
print(response.headers)

# 状态码
print(response.status_code)

能抓取什么样的数据?

  • 网页文本
    如HTML文档、Json格式的文本等。

  • 图片
    获取到的是二进制文件,保存为图片格式。

  • 视频
    获取到的是二进制文件,保存为视频格式。

例如: 获取图片

import requests
 
# 创建请求头

headers = {
"User-Agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
}

# 发送网络请求
response = requests.get(url=['https://www.baidu.com/img/bd_logo1.png'](http://www.baidu.com/img/bd_logo1.png'%2Cheaders),headers = headers)


# 将获取的二进制内容进行保存
with open('./baidu.png','wb') as f: f.write(response.content)

网页的解析方式

  • 直接处理
    例如: 请求回来的就是一段字符串,我们可以简单处理后直接保存

  • Json解析
    例如: Ajax请求回来的一般都是json格式的数据,我们就需要从json中拿出我们想要的数据。

  • 正则表达式

  • BeautifulSoup

  • PyQuery

  • XPath

解析库的选择可以根据爬取的网页具体情况酌情选择。

我们抓到的网页和浏览器中看到的不一样

情况: 有时候我们抓取到的内容都是HTML代码,css链接以及JavaScript的链接,真正网页中的数据并不会出现在我们抓却到的内容中。

原因:是因为有些内容的链接是放在JavaScript代码中的,所有说我们抓取到的只是HTML网页中的JavaScript外链, 并不是真正的网页显示的内容。

解决: 我们需要找到真正的内容链接就好了。

例如: 我们请求一下头条

import requests

# 创建请求头

headers = {
"User-Agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
}

# 发送网络请求

response = requests.get(url=['https://www.toutiao.com/'](http://www.toutiao.com/'%2Cheaders),headers = headers) print(response.text)

实际内容在下面的链接里:

解决动态网页的渲染问题

  1. 如上面的方法,分析Ajax请求,拿到请求链接,再次发送请求,获取内容。

  2. 使用selenium/webdriver (自动化的测试工具),就像浏览器一样加载网页。

from selenium import webdriver chrome = webdriver.Chrome() chrome.get('https://www.baidu.com')

保存

  • 文本
  • 数据库
  • 二进制文件(图片,视频 ,音频)
2020/02/21 posted in  爬虫

2. 网页基本组成与结构

HTML简介

超级文本标记语言(HyperText Markup Language)是标准通用标记语言下的一个应用,也是一种规范和标准,它通过标记符号来标记要显示的网页中的各个部分。网页文件本身是一种文本文件,通过在文本文件中添加标记符,可以 告诉浏览器如何显示其中的内容(如:文字如何处理,画面如何安排,图片如何显示等)。浏览器按顺序阅读网页文 件,然后根据标记符解释和显示其标记的内容,对书写出错的标记将不指出其错误,且不停止其解释执行过程,编制 者只能通过显示效果来分析出错原因和出错部位。但需要注意的是,对于不同的浏览器,对同一标记符可能会有不完 全相同的解释,因而可能会有不同的显示效果。

标签:用尖括号包围的关键词我们成为标签。通常HTML标签成对出现,如:、。

Ø 开始标签:标签对中的第一个标签是开始标签,也成为开放标签。如。

Ø 结束标签:标签对中的第二个标签是结束标签,也成为闭合标签。如。

元素:我们把匹配的标签对以及它们包围的内容称为元素。即(元素 = 开始标签 + 内容 + 结束标签)。

Ø 块级元素:在浏览器默认显示时以新行来开始(和结束)的元素。

Ø 内联元素:又称行内元素,在浏览器默认显示时在同一行按从左至右顺序显示,不单独占一行的元素。
属性:开始标签中那些以名称/值对的形式出现的内容,我们称之为属性。

HTML元素

根元素

<doctype> 定义文档类型。
<html> 定义 HTML 文档。

元数据元素

<head> 定义关于文档的信息。
<meta> 定义关于 HTML 文档的元数据。
<link> 定义文档与外部资源之间的关系,一般用于引入样式表。
<base> 定义页面上所有链接的默认地址或默认目标。
<title> 定义文档标题。
<style> 定义文档的样式信息。

脚本元素

<script> 定义客户端脚本。
<noscript> 定义当浏览器不支持脚本的时候所显示的内容

块元素

<body> 定义文档的主体。
<h1><h2>... <h6> 定义文档标题。
<p> 定义文档段落。
<blockquote> 定义块引用。
<ul><ul><dl> 定义列表。
<table> 定义表格。

列表元素

无序列表
<ul> 定义无序的列表。
<li> 定义列表项。
有序列表
<ol> 定义有序的列表。
<li> 定义列表项。
定义列表
<dl> 定义定义列表。
<dt> 定义定义术语。
<dd> 定义定义描述。

表格元素

<table> 定义表格。
<thead> 定义表格的页眉。
<tbody> 定义表格的主体。
<tfoot> 定义表格的页脚。
<th> 定义表格的表头行。
<tr> 定义表格的行。
<td> 定义表格单元。

文本元素

文本格式化元素

<em> 定义着重文字。
<strong> 定义加重语气。
<sup> 定义上标字。
<sub> 定义下标字。
<ins> 定义插入字。
<del> 定义删除字。
<b> 定义粗体文本。
<i> 定义斜体文本。
<big> 定义大号字。
<small> 定义小号字。

链接与图像

<a> 定义超链接
<img> 定义图像。
<map> 定义图像地图。
<area> 定义图像地图中的可点击区域。

<div><span>

<div> 定义文档中的分区或节(division/section)。
<span> 定义 span,用来组合文档中的行内元素。

表单元素

<form> 定义供用户输入的表单。
<input> 定义输入域。
<textarea> 定义文本域 (一个多行的输入控件)。
<lable> 定义一个控制的标签。
<select> 定义一个选择列表。
<option> 定义下拉列表中的选项。
<optgroup> 定义选项组。
<button> 定义一个按钮。
<fieldset> 定义域。
<legend> 定义域的标题。

CSS

CSS简介

CSS是一种定义样式结构如字体、颜色、位置等的语言,用于描述网页上的信息格式化和现实的方式。CSS样式可以 直接存储于HTML网页或者单独的样式单文件。无论哪一种方式,样式单包含将样式应用到指定类型的元素的规则。 外部使用时,样式单规则被放置在一个带有文件扩展名_css的外部样式单文档中。

2.2 CSS语法

  1. css由两部分组成:选择器和声明。

选择器指定来声明应用于那个或者那些元素;声明用于设置元素的样式,用大括号括起来里面用分号隔开每一条。

  1. <head>中,可以用 <style><link>标签。

  2. 选择器中有多项时,在前一项的前提下,后一项的样式为声明的样式,其他情况无效。

  3. id选择器:

    • css文件中:#red {color:red;}

    • HTML文件中: <p id="red"> red </p>

  4. 类选择器:

css文件中:.center {text-align:center}

HTML文件中: <h1 class="center"> center </h1>

  1. 背景属性:

background-color属性:(合理的英文颜色单词或#000000,默认值为transparent为透明)为元素设置背景色。background-image属性:(url(/i/emg_01.jpg),默认值为none)用图像做背景。

background-repeat属性:(默认repeat在所有方向重复,repeat-x在水平方向重复,repeat-y垂直方向重复,no-repeat不重复)设定重复方式。

background-position属性:(top、center、bottom每种情况的left、center、right三种位置共九种;(x,y),x和y由0%到100%从坐上到右下,也可以用数字表示像素,也可以混用)设置背景图像起始位置。

background-attachment属性:(fixed当页面其他部分滚动时背景不变)固定背景图像。

background-clip属性:(border-box背景被裁剪到边框盒,padding-box背景被裁剪到内边距框,content-box背景裁 剪到内容处)规定背景的绘制区域。

background-origin属性:(border-box背景被裁剪到边框盒,padding-box背景被裁剪到内边距框,content-box背景 裁剪到内容处)规定background-position属性的位置相对于什么来定位。

background-size属性:(x,y,可以为以父元素为基础的百分比或像素做单位;cover,扩展足够大,可能有的部分 无法显示;contain,扩展至适应内容区域的最大尺寸)设置背景图像的尺寸。

  1. 文本属性:

color属性:(合理英文颜色名,#00000,rgb(255,0,0))设定文本颜色。letter-spacing属性:(x,定义间距可以为负数单位像素)设定文本间距。

line-height属性:(x,可为百分比和像素,不能为负值)设定文本行高。text-align属性:(left,right,center,justify两端对齐)设定对齐方式。

text-decoration属性:(underline下划线,overline上划线,line-through横穿一条线,blink闪烁)文本划线样式修 饰。

text-indent属性:(x,可为以父元素为基础的百分比和像素)规定文本块首行文本缩进。text-shadow属性:(x,y,z水平阴影位置,垂直阴影位置,模糊距离,颜色)文本阴影。word-spacing属性:(x,定义间距可以为负数单位像素)设定字间距,单词以空格分开算。word-wrap属性:(break-word)在长单词或URL地址内部进行换行。

  1. 字体属性:

font属性:在一个声明中可以设置所有的字体属性。

font-style属性:(italic斜体,oblique倾斜,)设置字体倾斜样式。

font-variant属性:(small-caps显示小型大写字母的字体)设置为小型大写字母。font-weight属性:(x,400为默认,700为bold粗体)设置文本粗细。

font-size属性:(x,百分比或固定值)设置字体尺寸。font-family属性:为段落设置字体。

  1. 链接定义:

a:link {} 未被访问的链接

a:visited {} 已被访问的链接a:hover {} 鼠标指针移动到链接上a:active {}正在被点击的链接

hover要在link和visited之后,active要在hover之后。

text-decoration属性:(none去掉下划线,underline出现下划线)设置下划线。background-color属性:规定链接的背景色。

  1. 表格属性:

border-collapse属性:(collapse将边框合并为一个单一的边框)边框样式。caption-side属性:(top在顶端,bottom在低端)表格标题位置。

empty-cells属性:(hide不在空单元格周围绘制边框)是否显示空单元格。border-width属性:(x,y,z,w,上右下左,百分比或固定值)设置边框尺寸。border-color属性:(x,y,z,w,上右下左,四个颜色值)设置边框颜色。

width属性、height属性:(x,百分比或固定值)设置表格宽度和高度。

padding属性:(x,y,z,w,上右下左,四个位置内边距)声明所有的内边距,或者用padding-bottom,padding- left,padding-right,padding-top四个属性来替换。

border-style属性:(none无,dotted点,dashed虚线)定义边框样式。

margin属性:(x,y,z,w,上右下左,百分比或固定值)设置一个声明中的外边距。

css类型

内联方式

样式定义在单个的 HTML元素中内部样式表

样式定义在 HTML 页的头元素中外部样式表

将样式定义在一个外部的 CSS 文件中(.css 文件) 由 HTML 页面引用样式表文件

css选择器

  1. 标签选择器(如:body,div,p,ul,li)

  2. 类选择器(如:class=”head”,class=”head_logo”)

  3. ID选择器(如:id=”name”,id=”name_txt”)

  4. 全局选择器(如:*号)

  5. 组合选择器(如:.head .head_logo,注意两选择器用空格键分开)

  6. 继承选择器(如:div p,注意两选择器用空格键分开)

  7. 伪类选择器(如:就是链接样式,a元素的伪类,4种不同的状态:link、visited、active、hover。)

JavaScript

JavaScript简介

JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户 提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。

  1. 是一种解释性脚本语言。

  2. 主要用来向HTML(标准通用标记语言下的一个应用)页面添加交互行为。

  3. 可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。

  4. 跨平台特性,在绝大多数浏览器的支持下,可以在多种平台下运行(如Windows、Linux、Mac、Android、

iOS等)。

JavaScript语法

  1. js代码能直接嵌入网页的任何地方,通常放在 <head> </head>中,但会要求用户把所有js代码都下载解析执 行以后在呈现内容;

  2. 可以把代码单独的放在一个.js文件中,同时,多个页面可以引用同一份.js文件;

  3. 页面中可以多次编写 <script> </script>,但是浏览器会按照顺序执行这些JavaScript代码;

  4. JavaScript中每个语句以 ; 结尾 每个语句块以 {…..} 注释用//或/* */

  5. 所有类型都是定义变量都是用 var, 如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量;

hello.html

 <html>
     <head>
         <title>js \</title>
         <script type="text/javascript"> console.log("Hello javascript")
         </script>
     </head>
     <body>
     </body>
 </html>

 

外部样式表

test.js
 
 alert('Hello JS')

test.html

 <html>

     <head>
         <title>js \</title>
         <script type="text/javascript" src='test.js'> \</script>
     </head>
     <body>
     </body>
 </html>

火火的总结

  • HTML展示内容,网页的骨架
  • CSS美化页面{}
  • JS让页面动起来,提高浏览体验。
2020/02/21 posted in  爬虫

5. Json

数据分类

非结构化数据:html

处理方法: re,Xpath,bs4等

结构化数据:json

处理方法: 将json格式的数据转化成Python的数据类型

JSON

JSON是一种轻量级的数据交换格式,它使得人们很容易进行阅读和编写。同时也方便了机器进行解析和生成,适用  于进行数据交互的场景,比如网站前台与后台之间的数据交互。

clip_image001.jpg

JSON语法规则

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组

JSON 值

JSON 值可以是:

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在方括号中)
  • 对象(在花括号中)
  • null

JSON模块

通过Python的json模块,可以将字符串形式的json数据转化为字典,也可以将Python中的字典数据转化为字符串形式  的json数据。

Json 模块提供了四个方法: dumps(重点)、dump、loads(重点)、load。

dumps 和 dump

dumps(重点掌握)和dump 序列化方法

dumps只完成了序列化为str

dump必须传文件描述符,将序列化的str保存到文件中

# dumps 将“obj” 数据类型 转换为 JSON格式的字符串
dict1 = {
    'Code': 200,
    'Count': 657,
    'Posts': [
                {
                    'Id': 0,
                    'PostId': "1123178321664806912",
                    'RecruitPostId': 49691
                },
                {
                    'Id': 0,
                    'PostId': "1123178321664806912",
                    'RecruitPostId': 49691
                }
            ]
        }

json_dict = json.dumps(dict1) 
print(json_dict) 
print(type(json_dict))

 # dump 两个动作,一个动作是将”obj“转换为JSON格式的字符串,还有一个动作是将字符串写入到文件中,也就是说文件描述符fp是必须要的参数

with open('./a.json','w') as f:
    json_dict1 = json.dump(dict1,fp=f) 
    print(json_dict1)
    print(type(json_dict1))

loads 和 load

loads(重点掌握)和load 反序列化方法

load 只接收文件描述符,完成了读取文件和反序列化

loads 只完成了反序列化

# loads 将包含str类型的JSON文档反序列化为一个python对象
dic = json.loads('{"name":"Tom", "age":23}') 
print(dic)
print(type(dic))

# load 将一个包含JSON格式数据的可读文件饭序列化为一个python对象
with open("./a.json", "r",encoding='utf-8') as f:
    aa = json.load(f)
    print(aa) 
    print(type(aa))

参数介绍

对应于load和loads,dump的第一个参数是对象字典,第二个参数是文件对象,可以直接将转换后的json数据写入文  件,dumps的第一个参数是对象字典,其余都是可选参数。

dump和dumps的可选参数相同,这些参数都相当实用,现将用到的参数记录如下:

ensure_ascii  默认为True,保证转换后的json字符串中全部是ascii字符,非ascii字符都会被转义。如果数据中存在中文或其他非ascii字符,最好将ensure_ascii设置为False,保证输出结果正常。

indent 缩进,默认为None,没有缩进,设置为正整数时,输出的格式将按照indent指定的半角空格数缩进,相当实用。

separators 设置分隔符,默认的分隔符是(',', ': '),如果需要自定义json中的分隔符,例如调整冒号前后的空格数,可以按照(item_separator, key_separator)的形式设置。

sort_keys 默认为False,设为True时,输出结果将按照字典中的key排序。

2020/02/21 posted in  爬虫