把这两天敲的代码梳理一下。
使用python进行爬虫的话,urllib库使用的不多。这里介绍这个,只是为了打牢基础。
urllib库下比较常用的是request、parse和error函数,request和parse最常用。本文主要使用的为request.urlopen、request.urlretrieve,parse.urlencode。
本人使用pycharm,但鉴于jupyter notebook界面较为美观,有的代码我会放在jupyter notebook中进行实现。所有的抓取都是只抓取了源代码,后面的提取可以用正则表达式,这里省略(也不建议,因为后面有更好的方法)。
一、普通get请求。
以下载图片为例。在百度中以“圣诞树”为关键字进行搜索,随意选择一张图片,右击复制图片地址。输入:
# 普通get请求
importurllib.request
importurllib.parse
# 构建url & 伪装浏览器
url ='https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1544362938446&di=b1646d66ac7b7cfb703fd2ac08e11fe2&imgtype=0&src=http%3A%2F%2Fpic.58pic.com%2F58pic%2F11%2F04%2F75%2F91S58PICeU6.jpg'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
}
# 向浏览器发送请求
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
# 下载图片
withopen('tupian.jpg','wb')asf:
f.write(response.read())
运行后可在本地找到图片,如下图。
二、普通post请求
以请求百度翻译翻译python时的后台代码为例,通过检查后台运行过程,发现该请求为post请求,且附带如下图所示的data数据:
因此输入:
# 普通post请求
importurllib.request
importurllib.parse
# 构建url & 伪装浏览器
url ='https://fanyi.baidu.com/'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
}
# 构建post数据并处理
word =input('输入单词:')
data = {
'kw':word
}
data = urllib.parse.urlencode(data).encode()
# 发送请求
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request,data=data)
print(response.read().decode())
将此代码放到jupyter中实现如下图所示:
三、Ajax get请求
这里以爬取豆瓣电影科幻片排行榜后台代码为例,通过分析后台运行过程,发现它是以url的start和limit来控制显示的,如下图:
输入以下代码:
# Ajax get 请求
importurllib.request
importurllib.parse
# 构建url & 伪装浏览器
url ='https://movie.douban.com/j/chart/top_list?type=17&interval_id=100%3A90&action=&'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
}
# 构建请求数据和新url
page =int(input('第几页:'))
num =20
data = {
'start':(page-1)*num,
'limit':num,
}
query_str = urllib.parse.urlencode(data)
url = url + query_str
# 发送请求
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
# 输出
print(response.read().decode())
运行后输出结果如下:
四、Ajax post请求
这里以抓取肯德金店面信息为例。后台信息如下,可以看到,是post请求,且包括cname,pid等data数据,其中cname表示城市名称,pageIndex表示第几页,pageSize表示一页显示多少。
输入以下代码:
# Ajax post请求
importurllib.request
importurllib.parse
# 构建url & 伪装浏览器
url ='http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
}
# 构建请求数据
city =input('请输入城市:')
page =input('请输入页码:')
size =input('请输入每页显示数量:')
data = {
'cname':city,
'pid':'',
'pageIndex':page,
'pageSize':size,
}
data = urllib.parse.urlencode(data).encode()
# 发起请求
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request,data=data)
# 输出
print(response.read().decode())
运行结果如下:
五、一个复杂的get请求
这里以爬取百度贴吧某吧的主题为例。随意进入一个吧,如无损音乐吧,发现贴吧的下一页以50分界,即第一页的网址如下:http://tieba.baidu.com/f?kw=无损音乐&ie=utf-8&pn=0;第二页的网址如下:http://tieba.baidu.com/f?kw=无损音乐&ie=utf-8&pn=50;第三页的网址如下:http://tieba.baidu.com/f?kw=无损音乐&ie=utf-8&pn=100,很有规律性。
现在想爬取任意某页至某页的主题,且存放在文件夹里,可输入:
# 一个复杂的get请求
importurllib.request
importurllib.parse
importos# 用于建立文件夹
# 构建url & 伪装浏览器
url ='http://tieba.baidu.com/f?'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
}
# 构建请求数据
name =input('请输入吧名:')
start_page =int(input('请输入初始页码:'))
end_page =int(input('请输入结束页码'))
# 建立文件夹
if notos.path.exists(name):
os.mkdir(name)
# 使用for循环构建新url爬取多页
forpageinrange(start_page,end_page +1):
data = {
'kw': name,
'ie':'utf-8',
'pn': (page -1) *50,
}
url1 = urllib.parse.urlencode(data)
url_new = url + url1
# 请求浏览器
request = urllib.request.Request(url=url_new,headers=headers)
print('第%s页开始下载......'% page)
response = urllib.request.urlopen(request)
# 保存
filename = name +'_'+'.html'
filepath = name +'/'+ filename
print('第%s页结束下载......'% page)
运行后结果如下:
六、其他用法
1、urllib.error
# 异常处理
# URL error
importurllib.request
importurllib.parse
importurllib.error
url ='http://www.maodan.com/'
try:
response = urllib.request.urlopen(url)
print(response)
excepturllib.error.URLErrorase:
print(e)
# HTTP error
url2 ='https://blog.csdn.net/zcf1784266476/article/details/71335'
try:
response = urllib.request.urlopen(url2)
print(response)
excepturllib.error.URLErrorase:
print(e)
结果如下:
2、Handler 和 Opener的用法
# Handler & Opener
importurllib.request
importurllib.parse
url ='http://www.baidu.com/'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
}
# 创建Handler
handler = urllib.request.HTTPHandler()
# 通过Handler创建一个Opener,可用来发送请求,无需再用urlopen
opener = urllib.request.build_opener(handler)
# 构建请求对象
request = urllib.request.Request(url,headers=headers)
# 发送请求
response = opener.open(request)
print(response.read().decode())
结果如下:
3、再其他
还有一些proxy代理,cookie的代码,有空再整理上。
领取专属 10元无门槛券
私享最新 技术干货