目录
所用模块:requests
简单的对百度的访问
res.status_code 响应的HTTP状态码
res.text 响应内容的字符串形式
res.content 响应内容的二进制形式
res.encoding 响应内容的编码
import requests
# 发出http请求
res = requests.get("https://www.baidu.com")
# 查看响应状态
print(res.status_code)
#200就是响应的状态码,表示请求成功
#我们可以通过res.status_code的值来判断请求是否成功。
print(res.text)
#响应内容的字符串形式html
如出现RequestsDependencyWarning: urllib3 (1.26.4) or chardet (4.0.0) doesn‘t match a supported version!:
需要调整第三方库的版本
下载txt文件
res.text返回文本内容
用爬虫下载孔乙己的文章,网址是https://apiv3.shanbay.com/codetime/articles/mnvdu
re = requests.get('https://apiv3.shanbay.com/codetime/articles/mnvdu')
# 查看响应状态
print('网页的状态码为%s' %re.status_code)
with open('鲁迅文章.txt', 'w') as file:
# 将数据的字符串形式写入文件中
file.write(re.text)
下载图片等媒体
res.content用于图片、视频、音频等内容的获取、下载
用python进行下载:
res = requests.get('https://i-blog.csdnimg.cn/blog_migrate/7670dead475bdc5d9395cf3e4bc2e243.png')
pic1 = open('newpng.png','wb')
pic1.write(res.content)
html解析和提取
第三方库:BeautifulSoup(bs4)
pip install bs4
解析提取豆瓣读书 Top250🌟
import io
import sys
import requests
from bs4 import BeautifulSoup
###运行出现乱码时可以修改编码方式
#sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
###
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
res = requests.get('https://book.douban.com/top250', headers=headers)
soup = BeautifulSoup(res.text, 'lxml')
print(soup)
headers表示我们的请求网页的头,对于没有headers的请求可能会被服务器判定为爬虫而拒绝提供服务
通过 from bs4 import BeautifulSoup 语句导入 BeautifulSoup
然后使用 BeautifulSoup(res.text, lxmlr’) 语句将网页源代码的字符串形式解析成了 BeautifulSoup 对象
对于beautifulsoup对象
- find() 返回符合条件的首个数据
- find_all() 返回符合条件的所有数据
# 定位div开头 同时id为'doubanapp-tip的标签
div = soup.find('div', id='doubanapp-tip')
# 定位a抬头 同时class为rating_nums的标签
span = soup.find_all('span', class_='rating_nums')
print(div)
print(span)
通过页面元素检查定位信息位置:
通过寻找可以发现书本名字都在
<a href="https://book.douban.com/subject/1007305/" onclick=""moreurl(this,{i:'0'})"" title="红楼梦">
红楼梦 </a>
这样一个标签中,并且都包裹在
<div class="pl2">...</div>
div = soup.find_all('div', class_='pl2')
print(div.find('a'))
可以返回含有书本标题的标签了:
可以发现每个div设置了title,而title的值正是书本名字,那么只要加上索引,就成功返回了书本名称
div = soup.find_all('div', class_='pl2')
for info in div:
print(info.find('a')['title'])
但是我们发现这只有第一页的结果,点击跳转到第二页可以发现第二页的网址是这样的
随后可以发现后面的start=**相当于索引值,每页显示25本,"start=25"表示从第二十六本书开 始显示25本书在当前页面
所以添加循环后轻松实现了所有榜单的获取
for index in range(0,226,25):
res = requests.get('https://book.douban.com/top250?start=%d' %index, headers=headers)
soup = BeautifulSoup(res.text, 'lxml')
div = soup.find_all('div', class_='pl2')
for info in div:
print(info.find('a')['title'])
巩固一下之前学的excel自动化,我们把结果导入一个新的excel
首先初始化一个workbook
douban = openpyxl.Workbook()
douban.create_sheet(title='豆瓣读书榜单')
sheet = douban['豆瓣读书榜单']
再将循环改为:
for info, i in zip(div, range(index,index+26)):
sheet['a%d' %(i+2)].value = info.find('a')['title']
已经成功把书名放入表格
补充更多内容:
添加一个头部:
head = ['排名', '书名', '作者', '出版时间', '封面']
sheet.append(head)
添加排名,作者,出版时间,封面的信息
最终代码:
import io
import sys
import requests
import openpyxl
from bs4 import BeautifulSoup
###运行出现乱码时可以修改编码方式
#sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
###
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
douban = openpyxl.Workbook()
douban.create_sheet(title='豆瓣读书榜单',index=0)
sheet = douban['豆瓣读书榜单']
head = ['排名', '书名', '作者','出版社' ,'出版时间', '封面']
sheet.append(head)
for index in range(0,226,25):
res = requests.get('https://book.douban.com/top250?start=%d' % index, headers=headers)
soup = BeautifulSoup(res.text, 'lxml')
bookname = soup.find_all('div', class_='pl2')
authers = soup.find_all('p', class_='pl')
images = soup.find_all('img')
rimg =[]
for image in images:
if image['src'] != "/pics/read.gif":
rimg.append(image)
for image, auther, info, i in zip(rimg, authers, bookname, range(index, index+26)):
sheet['A%d' % (i+2)].value = i+1
sheet['b%d' % (i+2)].value = info.find('a')['title']
sheet['c%d' %(i+2)].value = auther.text.split('/')[0]
sheet['d%d' %(i+2)].value = auther.text.split('/')[-3]
sheet['e%d' %(i+2)].value = auther.text.split('/')[-2]
sheet['f%d' % (i+2)].value = image['src']
print('已获取%d本' % (index+25))
sheet.column_dimensions['B'].width = 28.0
sheet.column_dimensions['C'].width = 25.0
sheet.column_dimensions['D'].width = 30.0
sheet.column_dimensions['E'].width = 20.0
#设置a列的宽度
douban.save('豆瓣榜单.xlsx')