目录
请求头包装:urllib.request.Request() 方法
为url参数中的中文参数进行编码:urllib.parse.urlencode({dict})
另一种方法: urllib.parse.quote(string)
Python中做爬虫的模块
使用Python语言来编写爬虫代码需要得到模块的支持。模块就是已经写好的代码,我们这里不关注底层的实现,只需要知道如何使用相应的模块进行爬虫代码的编写即可。如果对底层代码感兴趣的可以去python的lib库中查看源代码。常用的有urllib、urllib2,(最新版本以统一为urllib),本篇文章就来讲urllib模块。
模块名导入:urllib.request
导入方式
1.import urllib.request
2.from urllib import request
常用方法:urllib.request.urlopen()
作用
向网站发起请求并获得相应对象
参数
1.URL:需要爬取的URL地址
2.TIMEOUT:设置超时等待时间,如果在指定的时间内未得到响应即抛出异常
最简单的爬虫代码
import urllib.request
response=urllib.request.urlopen("https://www.baidu.com")
html=response.read()
print(html)
这段代码会爬取百度的前端源代码,读者可以登录到百度网站上点鼠标右键选择查看源代码,来对比打印结果。如下图所示。结果似乎有点出人意料,为什么是一行输出。我们看到图中我用红线标记的b,这是python中bytes数据类型的显示方式。
如果我们要获取字符串类型的输出,还需要对代码进行一下加工,也就是将bytes进行转码,在python中bytes转string类型需要用到decode方法,想法用string转bytes需要用到encode方法。
import urllib.request
response=urllib.request.urlopen("https://www.baidu.com")
html=response.read().decode()
print(html)
小结
urllib.request.urlopen()将会返回response对象。response对象有以下常用方法
#获取bytes类型
bytes=response.read()
#获取String类型
string=response.read().decode()
#获取状态码
statu=response.getcode()
#获取url
url=reponse.geturl()
#补充
bytes转string:bytes.decode()
string转bytes:string.encode()
网站如何判断是人为的操作还是爬虫程序的操作
说起爬虫,这个问题是无法避免的,也是程序员讨论的最多的。那么网站是如何判断是何者所谓呢? 这就需要我们对http协议的报头信息有所了解。我们可以随意找一个网站,点击鼠标右键选择检查。选择NETWORK,如图所示。看到一个叫User-Agent的参数,后面有一长串信息,我们知道Mozilla是火狐浏览器,所以所这个操作在目前看来是人为的(我通过游览器访问的)。
那么爬虫程序的User-Agent是什么呢?我们可以通过以下方式进行查看。
编写一段代码,如下。url填写http://httpbin.org/get
import urllib.request
response=urllib.request.urlopen("http://httpbin.org/get")
html=response.read().decode()
print(html)
我们将会看到输出结果,很明显"User-Agent": "Python-urllib/3.6", 这一看就知道是python爬虫程序所为。
请求头包装:urllib.request.Request() 方法
通过urllib.request.Request() 方法,我们可以将请求头包装为浏览器的信息。代码如下
import urllib.request
url="http://httpbin.org/get"
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}
#重构请求头
req=urllib.request.Request(url = url,headers = headers)
#获取响应内容
response=urllib.request.urlopen("http://httpbin.org/get")
#输出响应内容
html=response.read().decode()
为url参数中的中文参数进行编码:urllib.parse.urlencode({dict})
看到这样一条url:https://www.baidu.com/s?wd=电影
如图所示
当我们用这样的url进行网页爬取结果如下。UnicodeEncodeError,编码错误。
这个时候我们的urllib.parse.urlencode({dict})就派上用场了,dict是字典集。
我们首先要对wd=电影这一参数进行编码,代码如下
import urllib.request
url="https://www.baidu.com/s?{}"
#参数编码
params = urllib.parse.urlencode({"wd": word})
url=url.format(params)
另一种方法: urllib.parse.quote(string)
与urlencoding方法不同的是,quote方法用于对字符串进行编码
import urllib.request
url="https://www.baidu.com/s?wd={}"
#参数编码
params=urllib.parse.quote("电影")
url=url.format(params)
urllib.parse.unquote()也可以用于将编码反编码成字符串
字符串拼接的三种方式
1.字符串相加
上面的代码就是用的字符串相加的方法。将url与params相加即可。
2.字符串格式化(占位符)
利用占位符进行字符拼接即可
url="https://www.baidu.com/s?%s" params=urllib.parse.urlencode({"wd":"电影"}) url=url % params
3.format()方法(推荐)
注意url里的{}括号,因为urllib.parse.urlencode返回的是字典集,所以需要用{}站位
url="https://www.baidu.com/s?{}" params=urllib.parse.urlencode({"wd":"电影"}) url=url.format(params)
基于百度搜索的爬虫程序
到目前为止,可以将上面讲的做一个归类,整理出一个小程序了。下面的程序是爬取百度页面,但是加入了关键字的搜索,可以按照关键词的不同来进行搜索,请求到页面后保存到本地。
import urllib.request
#获取url
def get_url(word):
url="https://www.baidu.com/s?{}"
params = urllib.parse.urlencode({"wd": word})
url=url.format(params)
return url
#请求并获取响应
def request_url(url,word):
#定义请求头和文件保存路径文件名
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
}
dir="C:\\Users\\Administrator\\Desktop\\新建文件夹\\%s.html" % word
# 重构请求头
req=urllib.request.Request(url=url,headers=headers)
# 获取响应内容
response=urllib.request.urlopen(req)
# 提取响应内容
html=response.read().decode('utf-8')
print(html)
# 存盘
with open(dir,"w",encoding='utf-8') as f:
f.write(html)
if __name__ == "__main__":
word=input("输入关键词:")
request_url(get_url(word),word)
当然这段代码肯定是有缺陷的,只能抓取到静态的数据,不能抓取如js,css,ajax等动态数据。所以呈现出来的页面大概如下。有一点一定要注意,百度会开启安全验证机制,即使你做了头伪装也无济于事。在这种情况下你将爬取不到页面。