2.基本库的使用【静态网页抓取】


使用urllib

在python2中有urllib和urllib2,而在python3中只有urllib

urllib是python中内置的http请求库。它包含了4个模块。

  • requests:最基本的http请求模块,可以用来模拟发送请求。
  • error:异常处理模块,如果请求错误,我们可以捕捉这些异常。
  • parse:一个工具模块,提供了许多URL处理方法,如拆分、解析、合并等。
  • robotparse:识别网站的robots.txt文件。然后判断哪些网站可以爬,哪些网站不可以爬。

发送请求

1.uropen()
urllib.request模块提供了最基本的构造HTTP请求的方法

import urllib.request
response=urllib.request.urlopen('https://www.python.org')
print(response.read().decode('utf-8'))
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))

在这里插入图片描述
使用read()方法可以得到返回的网页内容
调用status属性可以得到返回结果的状态码,200代表请求成功,404代表网页未找到

使用getheader方法并传递一个参数获得了响应头中的Server值

除了urlopen函数的第一个参数可以传递URL外,还可以传递其他内容,如data(数据)、timeout(超过时间)等。

timeout参数
timeout参数用于设置超时时间,单位为秒,意思是如果请求超过了设置的时间,还没有得到响应,就会抛出异常。若不指定该参数,就会使用全局默认参数

高级用法

代理

from urllib.error import URLError
from urllib.request import ProxyHandler, build_opener
proxy_handler = ProxyHandler({
    'http':'http://127.0.0.1:9743',
    'https':'https://127.0.0.1:9743'
})
opener = build_opener(proxy_handler)
try:
    response = opener.open('https://www.baidu.com')
    print(response.read() .decode('utf-8'))
except URLError as e:
    print(e .reason)

在这里插入图片描述

Cookies

import http.cookiejar, urllib.request
cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open ('http://www.baidu.com')
for item in cookie:
    print(item.name + "=" + item.value)

在这里插入图片描述

处理异常

URLError

它具备一个属性reason,即返回错误的原因
例如:

from urllib import request,error
try:
    response=request.urlopen('https://cuiqingcai.com/index.htm')
except error.URLError as e:
    print(e.reason)

输入一个不存在的网页,所以报错了

HTTPRrror

它是URLError的子类,专门用来处理HTTP请求错误,比如认证失败等等。它有4个属性。
code:返回HTTP状态码
reason:返回错误原因
headers:返回请求头

解析链接

urlparse
用于实现URL的识别和分段

from urllib.parse import urlparse
result=urlparse('https://baidu.com/index.html;use?id=5#comment')
print(type(result), result)

在这里插入图片描述

urlunparse
urlsplit
urlunsplit
urljoin
urlencode
。。。

分析Robots协议

利用urllib的robotparser模块,实现网站Robots协议的分析。

Robots协议也称为爬虫协议,全名叫网络爬虫排除标准协议。一般放到该站点目录的robots.txt文件中。

如图为百度的robots协议
在这里插入图片描述

from urllib. robotparser import RobotFileParser

rp=RobotFileParser()
rp.set_url('http://www.jianshu.com/robots.txt')
rp.read()
print(rp.can_fetch('*',"http://www.jianshu.com/p/67554025d7d"))
print(rp.can_fetch('*',"http://ww.jianshu.com/search?q-python&page=1&type=collections"))

先创建RobotFileParser对象,然后通过set_url方法设置了robot.txt的链接

使用requests

安装Requests

pip install requests

获取响应内容

import requests
r=requests.get('http://www.santostang.com/')
print("文件编码:",r.encoding)
print("响应状态码:",r.status_code)
print("字符串的响应体:",r.text)

这样就返回了一个名为 rresponse响应对象,里面存储了服务器响应的内容。
在这里插入图片描述

  1. r.text是服务器响应的内容,会自动根据响应头部的字符编码进行解码
  2. r.encoding是服务器内容使用的文本编码
  3. r.status_code 用于检测响应的状态码,如果返回200,表示请求成功;如果返回4xx,表示客户端错误,返回5xx,表示服务器错误响应。可以使用r.status_code来检测请求是否正确响应。
  4. r.content是字节方式的响应体,会自动节码gzip和deflate编码的响应数据
  5. r.json是Requests内置的JSON解码器

定制Requests

传递URL参数

为了请求特定的参数,我们通常在URL的查询字符中加入某些数据,如果我们自己构建URL,一般数据会跟在一个问号后面,如http://httpbin.org/get?key1=value1&key2=value2

在Requests中,可以把这些参数放在字典李,用params构建至URL里。例如key1=value1,key2=value2构建至http://httpbin.org/get里

import requests
key_dict={'key1':'value1','key2':'value2'}
r=requests.get('http://httpbin.org/get',params=key_dict)
print("URL已经正确编码:",r.url)
print("字符串的响应体:\n",r.text)

在这里插入图片描述

定制请求头

请求头Headers提供了关于请求、响应或其他发送实体的信息。对于爬虫而言,请求头十分重要,有的时候,如果没有请求头或者请求头和实际网页不一致,就可能无法返回正确的结果。
在这里插入图片描述
右键点击检查
在这里插入图片描述
点击Network,在左侧的资源栏找到需要请求的网页(http://www.santostang.com/),单击需要请求的网页,在Headers中可以看到 Requests 中 Headers 的详细信息
在这里插入图片描述
提取请求头中重要的信息,把代码改成:

import requests
headers={
    'Host': 'www.santostang.com',
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'
}
r=requests.get('http://www.santostang.com/',headers=headers)
print("响应状态码:",r.status_code)

**注意:**这里的Host字段的意思主要是,指明http报文的方向,访问的地点

发送POST参数

除了GET请求外,有时还需要发送一些编码为表单形式的数据,如在登陆的时候请求就是POST,因为如果使用GET请求,密码就显示在URL里,这是非常不安全的。

import requests
key_dict={'key1':'value1','key2':'value2'}
r=requests.post('http://httpbin.org/post',data=key_dict)
print("URL已经正确编码:",r.url)
print("字符串的响应体:\n",r.text)

在这里插入图片描述
这样的话,表单不存在于URL中,但又使用用于了请求。

超时

有时爬虫遇到服务器长时间不反悔,这时爬虫程序就会一直等待,造成爬虫没有顺利执行。

因此可以使用Requests中的timeout参数设置特定的表述结束后停止等待响应。意思是:服务器在timeout秒后没有应答,就返回异常。

我们把这个秒数设置成0.001,看看会抛出什么异常。

import requests
url='http://www.santostang.com/'
r=requests.get(url,timeout=0.001)

在这里插入图片描述

正则表达式

search

import re
connect='''hello 123 456'''
result=re.search('hello(.*?)3',connect).group(1)
print(result)
 12

使用search方法会返回第1个满足要求的字符串,一旦找到满足要求的字符串就会停止查找。

我们可以使用group这个方法来获取里面的值。
group里面的参数为几,就返回第几个括号里的值。

findall

import re
connect='''hello 123 456'''
result=re.findall('hello(.*?)3',connect)
print(result)
[' 12']

与search方法不同,使用findall方法会返回一个列表。

其他

贪婪和非贪婪
贪婪模式:.*
非贪婪模式:.*?
贪婪模式会尽可能 的匹配多个字符,而非贪婪模式就是尽可能的匹配少的字符

修饰符
例如,再匹配带有换行符的字符串中,如果我们使用原先的正则匹配就会出现错误,所以我们这时候就要使用修饰符。
在这里插入图片描述
在网页中,我们较为常见的是re.Sre.I
我们先看一段代码:

import re
connect='''hello 1
23 456'''
result=re.findall('hello(.*?)3',connect,re.S)
print(result)
[' 1\n2']

在findall函数参数里,我们加入re.S的参数,可以使得正则匹配忽略换行符

正则表达式提取技巧

不需要compile

大多数时候,我们不需要使用compile方法,因为在使用findall
方法时,findall方法中默认调用了_compile犯法,再调用findall方法。

先抓大再抓小

一些有效内容和无效内容混在一起时。
我们可以使用先抓大再抓小的技巧,重复匹配。

实战

Requests爬虫实践:TOP250电影数据

网站分析

  1. 使用检查功能查看该网页的请求头,提取重要的请求头信息
    在这里插入图片描述
headers={
    'Host': 'movie.douban.com',
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'
}

我们观察可以发现,一页有25个电影的信息,如果想要获取250个电影信息,我们需要获取总共10页

这时候我们会发现,点击第一页的时候网址为https://movie.douban.com/top250?start=0

点击第二页网址就变成了
https://movie.douban.com/top250?start=25
根据这个,我们就很好理解了,每增加一页,网页的start参数就增加25

这里使用了xpath的方法对网页数据进行筛选

import requests
import lxml.html

headers={
    'Host': 'movie.douban.com',
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'
}
num=0
for i in range(10):
    #拼接每一页的网址
    url='https://movie.douban.com/top250?start='+str(i*25)
    #获取网页源码
    html=requests.get(url,headers=headers,timeout=5).text
    #构建网页对象
    selector=lxml.html.fromstring(html)
    #使用xpath获取电影名称
    name_list=selector.xpath('//*[@id="content"]/div/div[1]/ol/li/div/div[2]/div[1]/a/span[1]/text()')
    #获取评分
    score_list=selector.xpath('//*[@id="content"]/div/div[1]/ol//div/div[2]/div[2]/div/span[2]/text()')
    #获取电影名句
    FamousSentences_list=selector.xpath('//*[@id="content"]/div/div[1]/ol/li/div/div[2]/div[2]/p[2]/span/text()')
    #print("第",str(i+1),"页名句数量:",len(FamousSentences_list))

    #打印每页的电影信息
    for j in range(25):
        num+=1
        print("top",str(num),":",name_list[j],"  评分:",score_list[j])
        #print("top",str(num),":",name_list[j],"  评分:",score_list[j],"  ",FamousSentences_list[j])

在这里插入图片描述
注意:对电影的经典名句进行获取时,发现有部分电影没有经典名句,这样就会出现下标越界的情况
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值