本文爬虫不涉及付费内容,所爬取数据都是公开的
1.request爬取静态加载数据
就拿爬取音乐歌单来举例吧,本人比较喜欢杨宗纬,就先爬取一下他的歌单吧。
首先是确定url,这个url就是你要爬的数据的地址。
url为https://music.163.com/artist?id=6066
url 确定之后就可以开始写爬虫了。
第一步,导入相关库
import requests
from lxml import html
from lxml import etree
import urllib
import re
第二步,写入url和请求头
写入headers,里面放入请求头是为了伪装成浏览器,如果不知道怎么来的可以自行百度,这里只教你怎么找到headers。
进入你想要爬取的url,按下F12打开开发者工具,点击Network,刷新一下页面,在Name里随便找一个点击,再找到Headers里面的Request Headers,里面的User-Agent参数就是我们要的headers。
url = 'https://music.163.com/artist?id=6066'
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
第三步,确定方法
现在已经有了url,headers,找到该页面的请求方法。
和上面一样,只不过最后是在这里。
很明显是GET方法,所以就用GET方法,编码用utf-8。
r = requests.get(url, headers=headers)
r.encoding = 'utf-8'
接下来就看看是否成功。
s = r.text
s
成功请求到了,接下来就是获得想要的数据了
第四步,获得数据
因为源码已经有了,现在唯一不确定的是我想要的歌单是否是动态加载。判断的方法很简单,第一个方法就是用xpath定位元素解析,查看数据是否存在。
首先你要学会xpath定位,如果不会的话可以到你想要的数据位置右键点击,到Copy,里面有选项为Copy Xpath,这种方法缺点就是只能定位一个元素,如果你想要爬取其他的就要自己写xpath定位。
我这里Xpath是//div[@class="ttc"]/span/a/b/@title
简单解释一下,/ 表示的是下一级标签,// 同理表示2级或多级,//div是我匹配div标签,但是div标签太多了,怎么能知道我要的是哪个呢,所以就用到了后面的class,因为我要的数据在b标签那里。
这时候写//div[@class="ttc"]//b/@title
是一样的,我上面是为让你们能好好理解 / 的作用。
好,理解了上面的Xpath之后就来获取数据吧
html = etree.HTML(s)
html.xpath('//div[@class="ttc"]/span/a/b/@title')
结果是有数据,但是不是我们想要的数据,应该是被加密了,反爬虫的手段。
还记得上面判断是否为动态加载的数据方法吗,第二种方法就是按下CTRL+F,查找你要的数据,看看所需数据是否在你请求到的网页源码里
看来是静态加载的,但是在Xpath定位获取数据的时候可能被加密了,才会出现上面的情况。
这里就需要用到正则了,正则太香了。如果你不会正则的话,可以去百度自行学习,并不难,但是掌握了之后匹配字符串,提取或者清洗数据很方便。
names = re.findall(r'<ul class="f-hide">(.*?)</ul>',s)
names
names = re.findall(r"<a href=(.*?)>(.*?)</a>",str(names))
names
因为爬取下来的数据终归是要保存下来的,所以我们可以用上面的数据做三列,歌曲名称,歌曲地址,歌曲id
song_url_list = []
song_names = []
for i in names:
split1 = i[0].split('"')[1]
song_url_list.append('https://music.163.com/#'+split1)
song_names.append(i[1])
song_url_list
song_id = [int(j) for i in names for j in re.findall(r'\"\/song\?id=(.*?)\"',i[