爬取该网址下的前三页数据(作品名,专辑名,时长)
链接为千千音乐:http://music.taihe.com/artist/2517
u1s1,并不喜欢这个歌手
刚开始做的时候,觉得挺简单的,直接使用beautifulsoup进行爬取,分析源代码。
actor = []
issue = []
time = []
url = 'http://music.taihe.com/artist/2517'
r = requests.get(url)
soup = BeautifulSoup(text,'lxml')
listall = soup.find_all("li")
list1all = soup.find_all('div',attrs={'class':'songlist-inline songlist-album overdd'})
list2all = soup.find_all('div',attrs={'class':'songlist-inline songlist-time'})
for i in listall:
if (i.find('span',attrs={'class':'songname'})):
actor.append(i.find('span',attrs={'class':'songname'}).find('a')['title'])
for i in list1all:
if(i.find('a')['title']):
issue.append(i.find('a')['title'])
for i in list2all:
time.append(i.string.strip())
data = {
'歌名':actor,
'专辑名':issue,
'时长':time
}
res = pd.DataFrame(data)
res.to_excel('深信服笔试.xls')
结果发现,没法爬取后两页的,因为翻页url不会变化。
翻页url不变的话,我们就应该检查网页元素,进入Networks,查看xhr,观察其随着翻页的变化。
尝试:
百度了一下,都是post加form data的,我们的网址是get方法,不管用。
直接将query string params的参数加到网址后面也不管用。
最终的话,通过分析Networks中的xhr文件,发现有这样一个链接http://music.taihe.com/data/user/getsongs?start=15&size=15&ting_uid=2517&.r=0.90405508416046551593676937657,它所指向的源代码就是我们要爬取的代码。
开始干活:
因为.r参数没有规律可循,并且删除掉发现不影响网页源码,因此直接使用http://music.taihe.com/data/user/getsongs?加上其他参数即可。
actor = []
issue = []
time = []
url = 'http://music.taihe.com/data/user/getsongs'
for start in [0,15,30]:
r = requests.get(url+'?start='+str(start)+'&size=15&ting_uid=2517')
#对网页源码进行处理,先将\u的数据转换为汉字,然后将制表符都去掉,然后将含有多个转义符的字段进行替换
text = r.text
soup = BeautifulSoup(text,'lxml')
listall = soup.find_all("li")
list1all = soup.find_all('div',attrs={'class':'songlist-inline songlist-album overdd'})
list2all = soup.find_all('div',attrs={'class':'songlist-inline songlist-time'})
for i in listall:
if (i.find('span',attrs={'class':'songname'})):
actor.append(i.find('span',attrs={'class':'songname'}).find('a')['title'])
for i in list1all:
if(i.find('a')['title']):
issue.append(i.find('a')['title'])
for i in list2all:
time.append(i.string.strip())
data = {
'歌名':actor,
'专辑名':issue,
'时长':time
}
res = pd.DataFrame(data)
res.to_excel('深信服笔试.xls')
return text
此处又出现了问题,转义符号的问题,我们所爬取的网页源码是原始字符串类型的,所以我们直接对爬取的源码进行打印,会发现转义符没有生效,这会影响soup对源码的解析。
解决方案:将制表符,回车符号替换为空,然后将含有多个转义符的字段进行替换。
此时写入文件成功,但会发现,写入的中文都会是一些转义文本,/u开头的。
解决方案:此处使用encode和decode将其转换为汉字就可以了。
代码如下:
import requests
import pandas as pd
import urllib.parse
from bs4 import BeautifulSoup
import re
import copy
def spider_wike():
actor = []
issue = []
time = []
url = 'http://music.taihe.com/data/user/getsongs'
for start in [0,15,30]:
r = requests.get(url+'?start='+str(start)+'&size=15&ting_uid=2517')
#对网页源码进行处理,先将\u的数据转换为汉字,然后将制表符都去掉,然后将含有多个转义符的字段进行替换
text = r.text.encode('utf-8').decode('unicode_escape').replace('\\n','').replace('\\r','').replace('\\t','').replace('\\"', '"').replace('\\\\', '\\').replace('\\/', '/')
soup = BeautifulSoup(text,'lxml')
listall = soup.find_all("li")
list1all = soup.find_all('div',attrs={'class':'songlist-inline songlist-album overdd'})
list2all = soup.find_all('div',attrs={'class':'songlist-inline songlist-time'})
for i in listall:
if (i.find('span',attrs={'class':'songname'})):
actor.append(i.find('span',attrs={'class':'songname'}).find('a')['title'])
for i in list1all:
if(i.find('a')['title']):
issue.append(i.find('a')['title'])
for i in list2all:
time.append(i.string.strip())
data = {
'歌名':actor,
'专辑名':issue,
'时长':time
}
res = pd.DataFrame(data)
res.to_excel('深信服笔试.xls')
return text
if __name__ == '__main__':
s =spider_wike()