python爬虫基础——urllib

把这两天敲的代码梳理一下。

使用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的代码,有空再整理上。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181209G13BEO00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励