python爬虫速成
基本语法
html每个节点包括节点名,属性、节点内容等。
resquest语法
例子一 爬取图片
思路方法:
1.打开https://qq.yh31.com/zjbq/网站,通过F12打开开发者工具,如下图
2.点击开发者工具的箭头,并选择网页上的一个模块,开发者工具可以定位到对于的html语句上,如图:
3.可以看到,我们直接打开https://qq.yh31.com/zjbq/网站,然后再其html上找图片元素对应的html代码,代码里有图片的网址,这样,我们只需要打开每个图片的网址然后下载了。
requests.get(url).content,context是指数据的二进制,一般指图片或者音乐视频等的网址打开后使用;
requests.get(url).text,该网址的text返回的是html。
import requests
import re
import os
image = '表情包'
if not os.path.exists(image):
os.mkdir(image)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0'
}
response = requests.get('https://qq.yh31.com/zjbq/', headers=headers)
response.encoding = 'GBK'
response.encoding = 'utf-8'
print(response.request.headers)
print(response.status_code)
t = '<img src="(.*?)" alt="(.*?)" width="160" height="120">'
result = re.findall(t, response.text)
for img in result:
print(img)
res = requests.get(img[0], headers=headers)
print(res.status_code)
s = img[0].split('.')[-1] # 截取图片后缀,得到表情包格式,如jpg ,gif
with open(image + '/' + img[1] + '.' + s, mode='wb') as file:
file.write(res.content)
例子二 爬取小说内容
代码思路:
- 打开网址https://www.shicimingju.com/book/shuihuzhuan.html
- 在开发者工具中很快找到每个章节的网址
- 3.打开每个章节的网址,在html中找到文章内容
import requests
from bs4 import BeautifulSoup
#诗词名句网
url = 'https://www.shicimingju.com/book/shuihuzhuan.html'
#U-A伪装
headers ={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
#请求响应
response = requests.get(url=url,headers=headers)
response.encoding='utf-8'
#数据解析
soup = BeautifulSoup(response.text,'lxml')
#找到所有章节
li_list = soup.select(".book-mulu > ul > li")#select返回的是列表
fp = open("book/水浒传.txt","w",encoding='utf-8')#fp之所以放这,是for循环每次只找到一章
for li in li_list:
#章节名
title = li.a.text
#章节网址
chapter_url = 'https://www.shicimingju.com'+str(li.a['href'])
#headers共用
#请求响应
chapter_response = requests.get(url=chapter_url,headers=headers)
chapter_response.encoding='utf-8'
#数据解析
charpter_soup = BeautifulSoup(chapter_response.text,'lxml')
content = charpter_soup.find('div',class_='chapter_content').text
#print(title+' 爬取完毕!')
print(title+"\n"+content)
fp.write(title+content)#将章节名和内容写入txt
例子三 爬取网易云飙升榜音乐
开发者工具里elements中很可能没有我们想要的资源,因此就需要去network中找。点击放大镜图标,可以对所有的包进行关键字搜索。
一个网址往往有?,这是get请求的请求参数,可以在paylode查看
在使用resp = requests.post(url=url, headers=headers, params=params)时,可以将请求参数通过params传到网址里,通过修改params达到切换网址的目的。开发者工具里的network有response是该包的html代码,preview显示html编译结果。
网易云网址是一个嵌套网址,在elements不方便查找榜单上每个音乐的网址,因此使用network去查找。
网易云音乐抓取过程:
1.找到网易云音乐榜单的网址,找到每个音乐的id,一般榜单位置的requests.post().text都是json的形式,因此可以转换成json格式,resp = requests.post(url=url, headers=headers, params=params).json()。
2.通过id完整每个音乐的位置,并下载
```python
import time
from multiprocessing.dummy import Pool
import requests
import os
filename = "网易云飙升榜//"
if not os.path.exists(filename):
os.mkdir(filename)
url = "https://music.163.com/weapi/v6/playlist/detail?csrf_token="
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"
}
params = {
"params": "5fFJz3vX8o556VRwH1lQ1VOPliD5GUpmLB0gF92Q4bRf4q6wXyfj9/4BQ8DJMwvDErkW4wg7lfU+9wMLRL8J/pQpgFWbMCRpGBAmLHAmiRA=",
"encSecKey": "571762ea14eec58ed6b4e2f230a031e2c777eb0c37fe9f1e3727d19910660c138be02fa469da2d5c139a86f59da13fad1bac3e065d01eaed594a6a575d61189c4db2e0d1b3bf1f0d10ac86a2fbad554f82a9722a22066546b2dbd356ea4e612649ceb79560004363b531bbf43344617bd204fe50362ade347c37a0b9008383de"
}
resp = requests.post(url=url, headers=headers, params=params).json()
dic = {}
result = []
for music_info in resp["playlist"]["tracks"]:
music_url = f'http://music.163.com/song/media/outer/url?id={music_info["id"]}.mp3'
dic = {
'url': music_url,
'name': music_info["name"]
}
result.append(dic)
start_time = time.time()
def musicDownload(dic):
print("正在下载-"+dic['name'])
music_file = requests.get(url=dic["url"], headers=headers).content
with open(filename + dic["name"] + ".mp3", "wb") as fp:
fp.write(music_file)
pool = Pool(20)
pool.map(musicDownload,result)
end_time=time.time()
time1=end_time-start_time
print(f"共耗时:{time1}")