python爬虫入门
一 . requests
requests简介:python中原生的一款基于网络请求的模块,功能强大,简单便捷,效率极高.
作用: 模拟游览器请求。
安装:pip install requests
使用:
- 指定url
- 发起请求
- 获取响应数据
- 持久化存储
- 实战:
爬取搜狗首页的页面数据
import requests
if __name__ == '__main__':
# 指定url
url = 'https://www.sogou.com/'
# 发起请求
response = requests.get(url=url)
# 获取响应数据
page_text = response.text
print(page_text)
# 持久化存储
with open('../page/sogou.html', 'w', encoding='utf-8') as fp:
fp.write(page_text)
print('爬虫结束')
二 . 数据解析
数据解析分类:xpath,bs4和正则。
原理:解析的局部文本内容都会在标签或标签对应的属性之间进行存储,进行指定标签的定位,标签或标签对应的属性中的数据进行提取(解析)
bs4
- bs4数据解析的原理:
1. 实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
2. 通过调用BeautifulSoup对象中相关属性或方法进行标签定位和数据提取 - 安装:
pip install bs4
,pip install lxml
- 导入:
from bs4 import BeautifulSoup
- 对象的实例化:
page_text = response.text
soup = BeautifulSoup(page_text,'lxml')
soup.tagName 返回html中第一次出现的tagName标签
soup.find('tagName') 等同于soup.tagName
属性定位
print(soup.find('div', class_/id/attr='column'))
soup.find_all('div') 返回符合要求的所有标签
-select
select('某种选择器(id,class,标签...选择器)') 返回的是一个列表
层级选择器
soup.select('.tang > ul > li > a') >表示一个层级
soup.select('.tang > ul a') 空格代表多个层级
获取标签之间的文本数据
- soup.a.text/string/get_text()两个属性一个方法
- text/get_text() 获取某一个标签中所有的文本内容
- string 可以获取标签下直系的文本
获取标签之间的属性值
- soup.a['href']
- 实战
爬取三国演义小说中所有的章节标题和章节内容
import requests
from bs4 import BeautifulSoup
if __name__ == '__main__':
# 对首页的页面数据进行爬取
headers = {
'User-Agent': 'Mozilla / 5.0(WindowsNT10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 87.0.4280.141Safari / 537.36'
}
url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
page_text = requests.get(url=url, headers=headers).text
# 在首页中解析章节的标题和详情页的url
# 1. 实例化BeautifulSoup对象,并将页面源码数据加载到该对象中
soup = BeautifulSoup(page_text,'lxml')
# 解析章节数据和详情页url
li_list = soup.select('.book-mulu > ul > li')
fp = open('./sangou','w',encoding='utf-8')
for li in li_list:
title = li.a.string
detail_url = 'https://www.shicimingju.com'+li.a['href']
# 对详情页发起请求,解析出章节内容
detail_text = requests.get(url=detail_url, headers=headers).text
# 解析出详情页中的章节内容
detail_soup = BeautifulSoup(detail_text,'lxml')
div_tag = detail_soup.find('div',class_='chapter_content')
# 解析到的章节内容
content = div_tag.text
fp.write(title+':'+content+'\n')
print(title, '爬取成功!!!')
xpath
- 原理:
- 实例化一个etree对象,并把需要解析的页面源码数据加载到该对象中去
- 调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获 - 安装:
pip install lxml
- 实例化etree对象:
etree.HTML('page_text')
- 属性定位:
//div[@class="table"] tag[@attrname="attrvalue"]
- 索引定位:
//div[@class="table"]/p[3] 索引是从1开始的。
注意点:
/从根节点开始定位,表示的是一个层级
//表示的是多个层级,可以表示从任意位置开始定位
取文本:
/text() 取到的列表需要用索引值取出文本,获取的标签中直系内容
//text() 标签中非直系的所有文本内容
取属性:
/@attrname
- 实战:爬取某网站上xx图片
import requests
from lxml import etree
import os
if __name__ == '__main__':
# 爬取页面源码数据
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
}
url = 'http://pic.netbian.com/4kmeinv/'
response = requests.get(url=url,headers=headers)
# response.encoding='utf-8'
page_text = response.text
# 解析数据 src和alt属性值
tree = etree.HTML(page_text)
li_list = tree.xpath('//div[@class="slist"]/ul/li')
if not os.path.exists('./pic'):
os.mkdir('./pic')
for li in li_list:
img_src = 'http://pic.netbian.com' + li.xpath('./a/img/@src')[0]
img_name = li.xpath('./a/img/@alt')[0] + '.jpg'
# 通用处理中文乱码的解决方式
img_name = img_name.encode('iso-8859-1').decode('gbk')
# print(img_name,img_src)
# 请求图片进行持久化存储
img_data = requests.get(url=img_src, headers=headers).content
img_path = 'pic/' + img_name
with open(img_path, 'wb') as fp:
fp.write(img_data)
print(img_name, '下载成功!!!')