在开始本文的阅读之前,我希望你已经看过了 循序渐进自学爬虫(一): 基础篇1, 并且对相关的知识点进行了了解。
一个简单的不能再简单的爬虫
基本思路:利用程序来 获取网页,提取信息,保存数据。
获取网页
我们正常的操作是在地址栏输入 URL ,然后回车,页面就有各种花花绿绿的稀奇古怪的小玩意了。但这是人的操作呀,代码怎么做呢?
不得不说 python 是极其强大的语言,比如我们即将用到的 requests
库。requests学习网址
一句话来概括其作用:requests
用来发送请求、传递参数并接收服务端响应。对应我们在百度搜索东西的操作就是:打开百度,输入要搜索的内容,然后等待展示。(描述不是很恰当,😄)
OK,用一个简单的例子进行说明:
import requests
def request_demo(url):
response = requests.get(url)
return response
if __name__ == "__main__":
url = 'https://image.so.com/'
response = request_demo(url)
print(response)
上述几行代码实现了请求网站https://image.so.com/
并获得响应的操作,这个时候终端会打印一个响应对象。
<Response [200]>
可以使用python内置函数 dir()
对响应对象进行属性的查看。可以重点关注一下 response.text, response.url
这几个属性。
print(dir(response))
还是废话多一点吧,因为我也不知道谁在读我的博文,万一是个小学生呢~
response.text 获取响应的文本内容
response.url 对哪个url作出的响应,说白了就是你请求的url
提取信息
细心的你已经发现了,response.text
的输出好像有点眼熟,是不是就像昨天刚学过的 html + css + jsvascript。点击直达网页源码
如果你有打开 检查 -> 控制台 的话,你会发现,你的输出居然和 elements 里的内容一模一样哎,这不就意味着你把他的网页爬下来了嘛~
一般这个时候都会有一盆冷水
这个内容这么多,我拿下来要干嘛?
起初作为兴趣爱好研究爬虫的时候,数据拿下来就是拿下来了,拿下来要干嘛,我 TM 是真的不知道要干嘛。
莫慌,幸好现在你遇到了我。
定个小目标,先挣他一个亿!(先把图片保存下来呗,管他好不好看,存下来再说)
来看一下经过简化后的 response.text
,就是一堆的 html 标签组成的文档。
<!DOCTYPE html>
<html class="w3c">
<head></head>
<body>
<header></header>
<div id="body">
<div class="block">
<section id="bd_focus">
<ul>
<li class="cur">
<a href="/z?ch=beauty&t1=595&src=banner_beauty&gid=" target="_blank">
<img src="https://p.ssl.qhimg.com/dmfd/400_300_/t01c0f0829b497a02da.png" alt="" />
<span class="content">
<span class="title">清新美女</span>
</span>
</a>
</li>
<li class="">
<a href="/z?ch=design&src=banner_design#/&gid=" target="_blank">
<img src="https://p.ssl.qhimg.com/dmfd/400_300_/t0115d9c0bbb606dfb4.jpg" alt="" />
<span
class="content">
<span class="title">设计素材</span>
</span>
</a>
</li>
</ul>
</section>
</div>
</div>
<footer></footer>
</body>
</html>
在一大堆的标签中有一个标新立异的存在:<img src="https://p.ssl.qhimg.com/dmfd/400_300_/t01c0f0829b497a02da.png" alt="" />
, 通俗的讲,这个 img 标签的 src 指向了一个地址,复制粘贴打开,搜噶,这就是他的图片地址呀。
那我们是不是只要拿到这个图片链接就可以把图片保存下来了?
管他呢,先拿下来再说。
xpath请移步:在我还是个学生的时候总结的xpath的用法
text = """
<!DOCTYPE html>
<html class="w3c">
<head></head>
<body>
<header></header>
<div id="body">
<div class="block">
<section id="bd_focus">
<ul>
<li class="cur">
<a href="/z?ch=beauty&t1=595&src=banner_beauty&gid=" target="_blank">
<img src="https://p.ssl.qhimg.com/dmfd/400_300_/t01c0f0829b497a02da.png" alt="" />
<span class="content">
<span class="title">清新美女</span>
</span>
</a>
</li>
<li class="">
<a href="/z?ch=design&src=banner_design#/&gid=" target="_blank">
<img src="https://p.ssl.qhimg.com/dmfd/400_300_/t0115d9c0bbb606dfb4.jpg" alt="" />
<span
class="content">
<span class="title">设计素材</span>
</span>
</a>
</li>
</ul>
</section>
</div>
</div>
<footer></footer>
</body>
</html>
"""
from lxml import etree
html = etree.HTML(text)
a_lst = html.xpath('//a')
res = [(i.find('img').get('src'), i.xpath('span/span/text()')[0]) for i in a_lst]
print(res)
代码解读: 通过 etree.HTML 构造一个 html 对象,然后就可以使用 xpath 选择器,这里选择了整个文档的 a 标签,然后拿到 a 标签下的 img 标签的 url 和 span 下的文本说明作为图片的标题。
输出就像这样:
[('https://p.ssl.qhimg.com/dmfd/400_300_/t01c0f0829b497a02da.png', '清新美女'), ('https://p.ssl.qhimg.com/dmfd/400_300_/t0115d9c0bbb606dfb4.jpg', '设计素材')]
保存数据
下面是一份请求图片url并把图片保存在本地的代码:
import os
import requests
def save_img(img_url, name):
path = ''
assert isinstance(img_url, str), '图片路径必须是字符串'
if not os.path.exists('./static'): # 判断根目录是否存在
os.mkdir(root)
path = './static/' + name + ".jpg" # 保存的地址
try:
r = requests.get(img_url)
with open(path, 'wb') as f: # 'wb'以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
f.write(r.content) # content返回二进制数据,所以使用'wb'
f.close()
print("文件保存成功")
except:
print("爬取失败")
if __name__ == '__main__':
save_img('https://p.ssl.qhimg.com/dmfd/400_300_/t01c0f0829b497a02da.png', '女孩')
now, 图片就保存成功啦,在当前文件夹 static 下就有你要的女孩子的照片了呢。
那么接下来的操作就简单了,东北大锅炖
这是一个完整的爬虫案例
import requests
from lxml import etree
import os
def request_demo(url):
response = requests.get(url)
ret = response.text
return ret
def parse(text):
html = etree.HTML(text)
a_lst = html.xpath('//li/a')
all_data = [(i.find('img'), i.xpath('span/span/text()')) for i in a_lst]
# 对空值做处理
res = []
for i in all_data:
if i[0] is not None and i[1]:
res.append((i[0].get('src'), i[1][0]))
return res
def save_img(img_url, name):
assert isinstance(img_url, str), '图片路径必须是字符串'
if not os.path.exists('./static'): # 判断根目录是否存在
os.mkdir(root)
path = './static/' + name + ".jpg" # 保存的地址
try:
r = requests.get(img_url)
with open(path, 'wb') as f: # 'wb'以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
f.write(r.content) # content返回二进制数据,所以使用'wb'
f.close()
print("文件保存成功")
except:
print("爬取失败")
def main():
url = 'https://image.so.com/'
text = request_demo(url)
res_list = parse(text)
for i in res_list:
save_img(i[0], i[1])
return None
if __name__ == "__main__":
main()
嗯哼,图片保存下来了。唉,我可真是个优秀的小天才~
技术总结
- 学会 python requests 库的操作,最起码可以访问成功一个网站并拿到返回值
- 学会 python xpath 选择器,可以用来做基本的定位
- python 程序的设计思想
嗯~学习呢我认为是一个个循序渐进的过程,这也是我为啥给我的爬虫系列的博文起名为循序渐进。爬虫涉及到的知识很多的,我会尽量的解释清楚,有不懂的地方可以留言哦~
所有的代码我都会托管到 github,大家可以进行查看 小北的github地址-爬虫系列