python爬虫从零基础到入门(一)
此贴主要是面向无基础或是基础比较差的小白。在学习爬虫的时候,最好是有一点python和html基础。如果没有基础,问题也不大,但最好学习一下,不然学习的过程会有点吃力。
因为是自学的,难免存在错误,如有错误,请给予指正。在这里将自己的心得和学习过程分享给大家,为大家提供一些思路,希望大家在学习的道路上少走一些弯路。
初识爬虫
- 什么是爬虫:
网络爬虫
是一种自动获取网页内容的程序,是搜索引擎的重要组成部分。网络爬虫为搜索引擎从万维网下载网页。一般分为传统爬虫和聚焦爬虫。
通俗来讲:爬虫就是收集互联网上信息的小程序,一般来讲,当我们需要收集一些商品价格,图片视频资源等信息的时候,我们会通过百度,谷歌,搜狗等搜索引擎,一个一个自己打开网页进行收集,这比较麻烦,你便写了一个程序,让程序按照你指定好的规则去互联网上收集信息,这便是爬虫,我们熟知的百度,谷歌等搜索引擎背后其实也是一个巨大的爬虫。
- 爬虫合法吗?
也许你可能会经常听到这样一句话:“爬虫是面向监狱式的编程”,这是一句玩笑话,但是因为爬虫被抓的例子还是有不少的,首先爬虫是一门技术,技术应该是中立的,合不合法其实取决于你使用目的,是由爬虫背后的人来决定的,而不是爬虫来决定的。另外我们爬取信息的时候也可以稍微‘克制’一下,能拿到自己想要的信息就够了。一般来说只要不影响人家网站的正常运转,也不是出于商业目的,人家一般也就只会封下的IP(可以用IP池解决),账号之类的,不至于法律风险。
- 什么样的数据可以爬取?
大部分网站都会有一个robots协议,在网站的根目录下会有个robots.txt的文件,里面写明了网站里面哪些内容可以抓取,哪些不允许。以淘宝为例——https://www.taobao.com/robots.txt 当然robots协议本身也只是一个业内的约定,是不具有法律意义的,所以遵不遵守呢也只能取决于用户本身的底线了。一般来说,只要是在网页上我们能看见的数据都能爬取,不过随着爬虫技术的普及,一般的网站针对数据都会做一些防爬机制。如淘宝网,就必须登录,才能浏览数据,一些网站进行了JS加密。但是有反扒机制,爬虫就有反反爬措施来应对。
编程的基础学习是比较枯燥的,所以下面的学习,我将采用知识点和案例实战贯穿来进行讲解。(后面对知识点进行系统的梳理)
爬虫一般流程
- 先由urllib的request,或requests打开Url得到网页html文档。
- 浏览器打开网页源代码分析元素节点。
- 通过Beautiful Soup或则正则表达式提取想要的数据。
- 存储数据到本地磁盘或数据库(抓取,分析,存储)。
网页审查元素
在讲解爬虫内容之前,我们需要先学习一项写爬虫的必备技能:审查元素。
审查元素
以百度为例:输入网址:https://www.baidu.com/

单击右键:选择审查元素(N);或按F12查看元素。

我们可以看到,右侧出现了一大推代码,这些代码就叫做HTML。什么是HTML?
超文本标记语言,是一种用于创建网页的标准标记语言。
娱乐一下

哇!我竟然这么有钱!可以买车,买房,走上人生巅峰,迎娶白富美了,(^ o ^)
我能有这么多钱吗?怎么可能,这肯定是假的。我要是有这么多钱,我还在这,我早就“上天”了。* # *
那我是怎么给“黑”进网站的呢?怎么可能,我要是有这技术,马云都没有我有钱,其实就是通过修改服务器返回的HTML信息。我们每个人都是”整容大师”,可以修改页面信息我们在页面的哪个位置点击审查元素,浏览器就会为我们定位到相应的HTML位置,进而就可以在本地更改HTML信息。

又例如:我叫张三,我又可以叫马云。


这可以为我们提供一些小功能,比如平时我们在网上要复制一段文字,可是他不让我复制,要我注册付钱,(怎么可能我一个穷人)我们就可以通过按F12,查看页面元素,箭头定位到我们要复制的内容,在html中进行复制。
说这么多,什么意思呢?浏览器就是作为客户端从服务器端获取信息,然后将信息解析,并展示给我们的。我们可以在本地修改HTML信息,为网页”整容”,但是我们修改的信息不会回传到服务器,服务器存储的HTML信息不会改变。刷新一下界面,页面还会回到原本的样子。这就跟人整容一样,我们能改变一些表面的东西,但是不能改变我们的基因。
第三方库简单介绍
这里先对requests 和BeautifulSoup进行简单的介绍,后续会进行详细的介绍。
requests
官方中文文档:https://2.python-requests.org/zh_CN/latest/
requests是用Python写爬虫用到最多的库了,
- 首先我们需要倒入requests模块;
import requests
- 接着我们尝试向baidu发起请求;
r = requests.get('https://www.baidu.com/')
- 我们现在获得来命名为r的response对象,从这个对象中我们便可以获取到很多信息,如:
- 状态码,200即为请求成功
- 页面Html5代码
# 返回请求状态码,200即为请求成功
print(r.status_code)
# 返回页面代码
print(r.text)
# 对于特定类型请求,如Ajax请求返回的json数据
print(r.json())
- 当然对于大部分网站都会需要你表明你的身份,我们一般正常访问网站都会附带一个请求头(headers)信息,里面包含了你的浏览器,编码等内容,网站会通过这部分信息来判断你的身份,所以我们一般写爬虫也加上一个请求头,这部分内容可以在页面元素的netWork中找到。
![在这里插入图片描述]()
- 针对post请求,也是一样简单;
# 添加headers
headers = {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit'}
# post请求
data = {'users': 'abc', 'password': '123'}
r = requests.post('https://www.weibo.com', data=data, headers=headers)
- 很多时候等于需要登录的站点我们可能需要保持一个会话,不然每次请求都先登录一遍效率太低,在requests里面一样很简单;
# 保持会话
# 新建一个session对象
sess = requests.session()
# 先完成登录
sess.post('maybe a login url', data=data, headers=headers)
# 然后再在这个会话下去访问其他的网址
sess.get('other urls')
beautifulsoup
Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
BeautifulSoup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful
Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。
简单来讲就是:把网页html中我们需要的内容匹配出来。
- 导入beautifulsou模块;
from bs4 import BeautifulSoup
- 对页面代码进行解析,这边选用对html代码是官方示例中使用的爱丽丝页面代码;
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
# 选用lxml解析器来解析
soup = BeautifulSoup(html, 'lxml')
- 我们现在获得一个命名为soup的Beautifulsoup对象,从这个对象中我们便能定位出我们想要的信息,如:
# 获取标题
print(soup.title)
# 获取文本
print(soup.title.text)
# 通过标签定位
print(soup.find_all('a'))
# 通过属性定位
print(soup.find_all(attrs={'id': 'link1'}))
# 标签 + 属性定位
print(soup.find_all('a', id='link1'))
打印结果如下:
<title>The Dormouse's story</title>
The Dormouse's story
[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]
[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]
案例实战
网易云音乐下载(根据排行榜来下载)
(先了解过程,不要求掌握。)
2020.6.7(代码通过测试,可运行)
代码
import requests
from bs4 import BeautifulSoup
import urllib.request
class LoadWYYMusic: # 下载指定网易云歌单歌曲到本地
def __init__(self, url):
self.music_list_url = url
self.music_base_outer_url = 'http://music.163.com/song/media/outer/url'
# 伪装爬虫
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"
}
def parser_url(self, url):
""" 解析网址
:param url: 网址
:return: 网址响应内容
"""
print(url)
response = requests.get(url, headers=self.headers)
with open("musiclist.txt", "w", encoding="utf-8") as f:
f.write(response.content.decode())
return response.content.decode()
def get_music_list(self, music_content):
""" 获取歌曲列表,并生成歌曲下载列表
:param music_content: 歌曲内容
:return: 歌曲列表
"""
# 使用bs4匹配出对应的歌曲名称和地址
s = BeautifulSoup(music_content, 'lxml')
music_content_items = s.find('ul', class_="f-hide")
print(music_content_items)
music_list = []
for music_item in music_content_items.find_all("a"):
music_dic = {}
print(music_item)
print("{} : {} ".format(music_item.text, music_item["href"]))
# 把信息保存到字典,再添加到列表中
music_dic["music_name"] = music_item.text
music_dic["music_url"] = self.music_base_outer_url + music_item["href"][5:] + ".mp3"
music_list.append(music_dic)
return music_list
def load_save_musics(self, musics_list):
""" 根据列表,下载歌曲
:param musics_list:
:return:
"""
music_counter = 0
print(musics_list)
for music in musics_list:
name = music["music_name"]
url = music["music_url"]
try:
print("开始下载歌曲:%s ..." % name)
urllib.request.urlretrieve(url, "%s.mp3" % name)
print("%s 下载成功" % name)
music_counter += 1
except:
print("%s 下载失败" % name)
print("歌曲下载完成")
return music_counter
def run(self):
# 1、获取歌曲内容网页
music_html = self.parser_url(self.music_list_url)
# 2、解析成歌曲列表
musics_list = self.get_music_list(music_html)
# 3、根据列表信息,下载歌曲
music_amount = self.load_save_musics(musics_list)
print("下载成功 %d 首歌曲" % music_amount)
if __name__ == "__main__":
# 歌曲地址 原网址 https://music.163.com/#/playlist?id=2272699928
#url = "http://music.163.com/playlist?id=893988336" # 网址修改包装
url ="https://music.163.com/discover/toplist?id=2884035"
load_wyy_music = LoadWYYMusic(url)
load_wyy_music.run()
效果

用IDLE运行的效果:

部分资源来源于网络,如有侵权,请联系本人予以删除!

浙公网安备 33010602011771号