网络爬虫基本认知

1.什么是爬虫

是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。通俗的讲: 就是模拟客户端发起网络请求,接收请求的响应,按照一定的规则,自动的抓取互联网信息的程序。

2.爬虫的基本流程

1. 分析网站,得到目标url
2. 根据url,发起请求,获取页面的HTML源码
3. 从页面源码中提取数据
 a.提取到目标数据,做数据的赛选和持久化存储
 b.从页面中提取到新的url地址,继续执行第二部操作
4. 爬虫结束:所有的目标url都提取完毕,并且得到数据了,再也没有其他请求任务了,这是意味着爬虫结束

3.网页的三大特征

1. 每一个网页都有一个唯一的url(统一资源定位符),来进行定位
2.网页都是通过HTML(超文本)文本展示的
3.所有的网页都是通过HTTP<超文本传输协议>(HTTPS)协议来传输的

4.通用爬虫和聚焦爬虫

通用网络爬虫 是 捜索引擎抓取系统(Baidu、Google、Yahoo等)的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份
聚焦爬虫,是"面向特定主题需求"的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于:聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。

5.Robot.txt 是什么,里面的参数是什么意思

Robots协议:(也叫爬虫协议、机器人协议等),全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取
User-agent:(识别是哪家的爬虫)
Allow: (允许爬取的目录)
Disallow:(不允许爬取的目录)

6.七层协议

(从上到下)
应用层:为用户的应用程序提供网络服务的(http,https,ftp....)
表示层:负责端到端的数据信息可以被另一个主机所理解和识别,并且按照一定的格式将信息传递到会话层
会话层:会话层是管理主机之间的会话进程,负责建立,管理,和终止会话进程
传输层:进行数据传输的(TCP UDP)
网络层:路由器
数据链路层:网桥,交换机
物理层:网线网卡,集线器,中继器

7.http和https协议

HTTP协议(HyperText Transfer Protocol)中文名叫超文本传输协议: 是用于从网络传送超文本数据到本地浏览器的传送协议
HTTPS协议(Hypertext Transfer Protocol over Secure Socket Layer)简单讲是HTTP的安全版,在HTTP协议的基础上加入SSL层(HTTP+SSL) 。 SSL(Secure Sockets Layer 安全套接层)主要用于Web的安全传输协议,在传输层对网络连接进行加密,保障在Internet上数据传输的安全

8.url的基本组成部分

URI(Uniform Resource Identifier):统一资源标识符
URL(Uniform / Universal Resource Locator的缩写):统一资源定位符,是用于完整地描述Internet上网页和其他资源的地址的一种标识方法。
URN(Universal Resource Name):统一资源名称,只命名资源而不指定如何定位资源

9.发起一个请求的基本流程

1.当用户 在浏览器的地址栏中输入一个URL并按回车键之后(会先经过DNS服务将域名解析为ip),浏览器会向HTTP服务器发送HTTP请求。HTTP请求主要分为“Get”和“Post”两种方法
2.当我们在浏览器输入URL http://www.baidu.com 的时候,浏览器发送一个Request请求去获取 http://www.baidu.com 的html文件,服务器把Response文件对象发送回给浏览器。
3.浏览器分析Response中的 HTML,发现其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。 浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。
4.当所有的文件都下载成功后,网页会根据HTML语法结构,完整的显示出来了。

10.get请求和post请求的区别

1.GET是从服务器上获取数据,POST是向服务器传送数据
2.GET请求参数都显示在浏览器网址上,POST请求参数在请求体当中,消息长度没有限制而且以隐式的方式进行发送

11.请求头参数和响应头里面的参数

  • 常用的请求报头(Request Headers)
    1.User-Agent (浏览器名称),客户浏览器的名称
    2. Cookie (Cookie),Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
    3. Referer (页面跳转处),表明产生请求的网页来自于哪个URL
    4. Content-Type (POST数据类型)
    5. Host (主机和端口号)
    6. X-Requested-With: XMLHttpRequest(表示是一个Ajax异步请求)
    7. Connection (链接类型) Connection:表示客户端与服务连接类型
    8. Upgrade-Insecure-Requests (升级为HTTPS请求)
    9. Accept (传输文件类型)
    10. Accept-Encoding(文件编解码格式)
    11. Accept-Language(语言种类)
    12. Accept-Charset(字符编码)
  • 常用的响应报头(Response Headers了解)
    1.Cache-Control:must-revalidate, no-cache, private。(是否需要缓存资源)
    2. Connection:keep-alive(保持连接)
    3. Content-Encoding:gzip(web服务器支持的返回内容压缩编码类型
    4. Content-Type:text/html;charset=UTF-8(文件类型和字符编码格式)
    5. Date:Sun, 21 Sep 2016 06:18:21 GMT(服务器消息发出的时间)
    6. Expires:Sun, 1 Jan 2000 01:00:00 GMT(响应过期的日期和时间)
    7. Pragma:no-cache 这个含义与Cache-Control(是否缓存资源)等同
    8.Server:Tengine/1.4.6(服务器和服务器版本)
    9. Transfer-Encoding:chunked,这个响应头告诉客户端,服务器发送的资源的方式是分块发送的
    10. Vary: Accept-Encoding,告诉缓存服务器,缓存压缩文件和非压缩文件两个版本,现在这个字段用处并不大,因为现在的浏览器都是 支持压缩的

12.请求常见的状态码

1. 100~199:表示服务器成功接收部分请求,要求客户端继续提交其余请求才能完成整个处理过程
2. 2xx:表示服务器成功接收请求并已完成整个处理过程。200(OK 请求成功)
3.3xx:为完成请求,客户需进一步细化请求。例如:请求的资源已经移动一个新地址、 常用。301: 永久重定向;302: 临时重定向(所请求的页面已经临时转移至新的url)
4. 4xx:客户端的请求有错误。
400:错误请求,服务器无法解析请求;
401:未授权,没有进行身份验证;
403:服务器拒绝访问;
404:服务器无法找到被请求的网页;
405:请求方式不被允许;408:请求超时
5. 5xx:服务器端出现错误。
500:服务器内部错误;
501:服务器不具备完成请求的功能;
503:服务器不可用

13.bytes类型和str字符串类型的相互转换,bytes和bytearray的区别

str类型使用encode方法转化为bytes类型 bytes类型通过decode转化为str类型
bytearray和bytes不一样的地方在于,bytearray是可变的

14.如何发起一个get请求

使用urllib发起请求:from urllib import request
输入目标url地址:url = 'http://www.baidu.com/'
使用urlopen方法模拟浏览器发起请求:response = request.urlopen(url)
从response响应结果中获取状态码:code = response.status
获取页面源码的二进制数据:b_html = response.read()
获取响应的响应头部(Response Headers):res_headers = response.getheaders()
获取响应头中指定参数的值:cookie_data = response.getheader('Set-Cookie')
reason返回一个响应结果的原因:reason = response.reason

15.urllib模块的基本使用

  • request: 它是最基本的HTTP请求模块,可以用来模拟发送请求,就像在浏览器中输入网址,然后敲击回车键一样,使用的时候只需要给库方法传入相关的URL和相关的参数即可

urlopen()的使用:
1.request.urlopen():使用URLopen方法模拟浏览器发起请求

1.request.urlopen():使用URLopen方法模拟浏览器发起请求
 # 目标url
url = 'http://www.baidu.com/'
# request.urlopen():使用URLopen方法模拟浏览器发起请求
response = request.urlopen(url)
"""
url,请求目标url地址
data=None,默认情况下为none,表示发起的是get请求,不为None,则发起的是一个post请求
timeout,设置请求的超时时间
cafile=None,设置证书
cadefault=False,是否要使用默认证书(默认为false)
context=None:是一个ssl值,表示忽略ssl认证
"""
html = response.read()
z_html = html.decode()
print(z_html)
#是一个ssl值,表示忽略ssl认证(如果请求出现了ssl证书认证错误,
#我们就需要设置ssl._create_unverified_context(),忽略证书认证)
content = ssl._create_unverified_context()
response = request.urlopen(url,timeout=10,context=content)
#从response响应结果中获取参数
#状态码
code = response.status
print(code)
#获取页面源码的二进制数据
b_html = response.read()
print(type(b_html),len(b_html))
#获取响应的响应头部(response headers)
res_headers = response.getheaders()
print(res_headers)
#获取响应头中指定参数的值
cookie_data = response.getheader('Set-Cookie')
print(cookie_data)
#reason返回一个响应结果的原因
reason = response.reason
print(reason)
#需要先构建一个request对象
"""
url:发起请求的url地址
data=None, 默认情况为None,表示发起的是一个get请求,不为None,则发起的是一个post请求
headers={},设置请求头(headers对应的数据类型是一个字典)
origin_req_host=None, (指定发起请求的域)
unverifiable=False,忽略SSL认证
method=None:指定发起请求的方式
"""
req_header = {
    'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
# url作为Request()方法的参数,构造并返回一个Request对象
req = request.Request(url,headers=req_header)

#根据构建的req请求对象发起请求
response = request.urlopen(req)
  • User-Agent 用不同的浏览器在发送请求的时候,会有不同的User-Agent头
from urllib import request
import random
# 使用随机ua发起请求
USER_AGDNTS = [
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
    'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0',
    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
    'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
]

url = 'http://www.baidu.com/'
#携带请求头,需要先创建一个Request对象
# url,:发起请求的url
# data=None, :默认为None,表示一个get请求
# headers={}:设置请求头,对应的是一个字典类型的参数
req_header = {
    'User-Agent':random.choice(USER_AGDNTS)
}
#构建一个request对象
req = request.Request(url,headers=req_header)

#根据Request对象发起请求
response = request.urlopen(req)

  • 使用fakeuseragent随机ua发起请求
from fakeuseragent import UserAgent
#实例化一个UA
user_agent = UserAgent()

#获取google浏览器的ua
print(user_agent.chrome)
#获取火狐浏览器的ua
print(user_agent.firefox)
#获取safar浏览器的ua
print(user_agent.safari)

  • error: 异常处理模块,如果出现请求错误,我们可以使用这个模块来捕获异常,然后进行重试或者其他操作,保证程序不会意外终止.

# urllib.error:在发起请求过程中,可能会因为各种情况
# 导致请求出现异常,因而导致代码崩溃,所以要处理这些异常请求
from urllib import error,request

#error.URLError

def check_urlerror():
    '''
    1.没有网络
    2.服务器连接失败
    3.找不到指定服务器
    :return:
    '''
    url = 'http://www.baiduxxx.com/'
    try:

        response=request.urlopen(url,timeout=0.01)
        print(response.status)
    except error.URLError as err:
        # [Errno -2] Name or service not known   未知服务器
        # [Errno -3] Temporary failure in name resolution  没网
        # time out 请求超时
        print(err.reason)
check_urlerror()

# error.HTTPError 是 URLError的子类

def check_httperror():
    url = 'https://www.qidian.com/all/nsacnscn.htm'
    try:
        response = request.urlopen(url)
        print(response.status)
    except error.HTTPError as err:
        # httperror的三个属性
        # 返回错误原因
        print(err.reason)
        # 状态码
        print(err.code)
        # 响应头
        print(err.headers)
    except error.URLError as err:
        print(err.reason)
check_httperror()

  • parse: 这是一个工具模块,提供了许多url的处理方法,比如拆分,解析,合并等等
# urllib的parse模块主要是实现url解析,合并,编码,解码
from urllib import parse

# 实现了url的识别和分段
url = 'httpsL://www.1712B.com/daxuesheng?name=zs#123'
'''
url:要解析和拆分的url
scheme='':设置协议,只有在url没有协议的情况下才会生效
allow_fragments=True:是否忽略锚点,默认为True表示不忽略
'''

result=parse.urlparse(url)
'''
(scheme='https'(协议), netloc='www.1712B.com'(域), 
path='/daxuesheng'(路径), params=''(可选参数), 
query='name=zhangsan'(查询参数), fragment='123'(锚点))
'''
# 取出拆分后的某一个参数
print(result.scheme)
# 可以实现url的组合
data = [sub_str for sub_str in result]
print('-------',data)
full_url=parse.urlunparse(data)
print(full_url)

# parse.urljoin需要传递一个基类url,根据基类将某一个不完整的url拼接完整
sub_url = '/p/12345'
base_url= 'httpsL://www.1712B.com/daxuesheng?name=zs#123'
full_url=parse.urljoin(base_url,sub_url)
print(full_url)

# 将字典类型参数,序列化为url的编码格式的字符串
parmars = {
    'name':'张三',
    'class':'1712B'
}
result = parse.urlencode(parmars)
print('urlencode',result)

# 反序列化,将url编码格式的字符串,转为字典类型
result = parse.parse_qs(result)
print('parse.parse_qs',result)

# 可以将中文字符,转为url编码格式
kw = '刚刚'
result=parse.quote(kw)
print('quote',result)

# 将url编码进行解码
result = parse.unquote(result)
print(result)

# 最常用的 urljoin,urlencode两个方法

16.正则

.:表示匹配除了换行符之外的任意字符
\:转义字符
[a - z]: 匹配a - z里面的任意一个字符

\d: 匹配数字 -> [0 - 9]
\D: 匹配非数字 [ ^\d]
\s: 匹配空白字符(空格,\n,\t...)
\S: 匹配非空白字符 
\w: 匹配单词字符 [A - Za - z0 - 9_]
\W: 匹配非单子字符

^:匹配以...开头
$:匹配以....结尾

(): 分组
|:或

多字符匹配
*:匹配*前面的字符任意次数
+: 匹配+号前面的字符至少1次
?: 匹配?前面的字符0次或1次
{m}: 匹配
{m}
前面的字符m次
{m, n}: 匹配
{m, n}
前面的字符m
~n次

非贪婪匹配
* ?
+?
??
{m, n}?
'''
import re

#把正则表达式构建为一个pattern对象
sub_str = 'abcdefabcd'
pattern = re.compile('b')
#从字符串的起始位置开始匹配,开头就必须符合正则规则,
# 如果匹配到结果了返回结果,如果匹配不到返回None,单次匹配
result = re.match(pattern,sub_str)
print(type(result))
if result:
    print(result.group())

#在整个字符串中进行匹配,同样是单次匹配,匹配到结果立即返回
#匹配不到则返回None
result = re.search(pattern,sub_str)
print(result.group())

# 再整个字符串中进行匹配,匹配出所有符合正则规则的结果,
# 以列表的形式返回
result = re.findall(pattern,sub_str)
print(result)

#再整个字符串中进行匹配,匹配出所有符合正则规则的结果,
#但是返回的是一个迭代器
result = re.finditer(pattern,sub_str)
# <class 'callable_iterator'>
print(type(result))
for note in result:
    #<class '_sre.SRE_Match'>
    print(type(note))
    print(note.group())
#替换re.sub()
url = 'http://www.baidu.com/s?kw=aaa&pn=20'
# pattern, \正则规则
# repl, \要替换的字符串
# string,原始字符串
pattern = re.compile('pn=\d+')
result = re.sub(pattern,'pn=30',url)
print(result)

#分割re.split()
pattern = re.compile('[=:&]')
#pattern, string
result = re.split(pattern,url)
print(result)

17.cookiejar使用

# 使用cookiejar的目的:管理cookiejar,保存cookie值,
# 一旦储存cookie后,下一次发起请求的时候就会携带cookie
# cookie是保存在内存里面的,最后会进行垃圾回收,
from urllib import request,parse
from http.cookiejar import CookieJar

#创建cookiejar对象,目的如上
cookie_jar = CookieJar()

# 自定义HTTPCookieProcessor创建handler处理器
handler=request.HTTPCookieProcessor(cookie_jar)

# 自定义opener
opener = request.build_opener(handler)

18.urllib下使用代理

  • 代理的作用
    1.突破自身IP访问限制
    2.访问一些单位或团体内部资源
    3.提高访问速度
    4.隐藏真实IP

19.requests简单使用

Requests 继承了urllib的所有特性。Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的URL和 POST 数据自动编码。

# requsets模块:是对urllib的封装,可以实现urllib的所有功能
# 并且api调用更加简单方便

import requests


# url = 'http://www.baidu.com/'
url = 'http://www.sina.com/'
# url 要请求的url目标
# parms: get请求后面要拼接的参数
'''
    :param method: 要发起什么类型的请求
    :param url: 要请求的目标url
    :param params: get 后面要拼接的参数
    :param data: Dictionary, post请求的表单数据
    :param json: 传递json数据跟上面的data效果一样
    :param headers: (optional) Dictionary 请求头.
    :param cookies: (optional) Dict or CookieJar object (设置cookies信息模拟用户请求)
    :param files: 上传文件      
    :param auth: 网站要验证的信息(账号和密码).
    :param timeout:设置请求超时时间 (optional)  
    :type allow_redirects: bool,是否允许重定向
    :param proxies: (optional) Dictionary(设置代理) 
    :param verify:  Defaults to ``True``.(忽略认证证书,默认为True表示不忽略)
    
'''
# response = requests.get(url)

req_header = {
    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:59.0) Gecko/20100101 Firefox/59.0'
}
parmars = {
    'wd':'豆瓣',
}
response = requests.get(url,params=parmars,headers=req_header)

# 从响结果中获取的信息
# (这里得到解码后的字符串)
html = response.text
# 如果使用response.text出现乱码
# 方式一 response.content.decode('')
# 方式二 response.encoding=''设置编码类型
# 获取bytes类型数据
b_html = response.content
# 获取状态码
code = response.status_code
# 获取响应头
response_header = response.headers
# 获取请求头
req_headers=response.request.headers
# 当前请求url地址
current = response.url
#response.json():可以将json字符串转为python数据类型

19.Xpath与lxml

xpath:可以在xml中查找信息,对xml文档中的元素进行属性的提取
xml:设计目的是为了传输数据,结构和html相像,是一种标记语言

xpath常见语法:
nodename : 选取此节点的所有子节点
/  : 从根节点开始查找
//  : 匹配节点不考虑节点的位置
.  : 选取当前节点
..  : 选取当前节点的父节点
a/@href   : 取标签数据
a/text() : 取标签文本
a[@class='123']  :  根据class属性寻找标签
a[@id='123']    : 根据id属性寻找标签
a[@id='123'][last()] : 取最后一个id为123 的 a标签
a[@id='123'][postion()<2]  : 取前两个id为123的 a标签

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容