爬虫学习笔记02-基本模块
Request
概念:Request是python中原生的一款基于网络请求的模块。
特点:功能强大,简单便捷,效率极高。
作用:模拟浏览器发请求。
使用方式:(requests 模块的编码流程)
-指定url
-发起请求
-获取响应数据
-持久化存储
环境安装:
pip install requests
实战代码
#爬取搜狗首页的页面数据
import requests
if __name__ == "__main__":
# step1:指定url
url = 'https://www.sogou.com/'
# step2:发起请求,get方法会返回一个响应对象
response = requests.get(url=url)
# step3:获取响应数据,text返回字符串形式的响应数据
page_text = response.text
print(page_text)
# step 4:持久化存储
with open('./sogou.html', 'w', encoding='utf-8') as fp:
fp.write(page_text)
print('爬取数据结束!!!')
#爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
import requests
if __name__ == "__main__":
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3861.400 QQBrowser/10.7.4313.400'
}
url='https://www.sogou.com/web'
#处理url携带的参数:封装到字典中
kw=input('enter a word:')
param={
'query':kw
}
response = requests.get(url=url,params=param,headers=headers);
page_text = response.text
filename = kw+'.html'
with open(filename,'w',encoding='utf-8') as fp:
fp.write(page_text)
print(filename,'保存成功!!!')
#爬取豆瓣电影分类排行榜
import requests
import json
if __name__ == "__main__":
url='https://movie.douban.com/j/chart/top_list'
param={
'type':'24',
'interval_id':'100:90',
'action':'',
'start':'1',#从库中的第几部电影去取
'limit':'20',#一次取出的个数
}
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36'
}
response=requests.get(url=url,params=param,headers=headers)
list_data=response.json()
fp=open('./douban.json','w',encoding='utf-8')
json.dump(list_data,fp=fp,ensure_ascii=False)
print('over!!!')
#需求:爬取肯德基餐厅查询
import requests
if __name__=="__main__": url='http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
params={
'cname':'',
'pid':'',
'keyword':'',
'pageIndex':'1',
'pageSize': '10'
}
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36'
}
response=requests.get(url=url,params=params,headers=headers)
text_list=response.text
fp=open('./kfc.html','w',encoding='utf-8')
fp.write(text_list)
print(text_list)
print('over!!!')
动态加载数据
-
首页对应的企业信息数据是通过ajax动态请求到的
-
通过对详细页url的观察发现:
- url的域名都是一样的,只有携带的参数(id)不一样
- id值可以从首页对应的ajax请求到的json串中获取
- 域名的id拼接处一个完整的企业对应的详细页的Url
-
详细页的企业详细数据也是动态加载出来的,观察后发现所有的post请求的Url都是一样的,只有参数的id是不同的。如果我们可以批量获取多家企业的id后,就可以将id和url形成一个完整的详细页对应信息
#需求:爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据
import requests
import json
if __name__=='__main__':
#批量获取不同企业的Id值
url='http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36'
}
for page in range(1,6):
page=str(page)
data={
'on': 'true',
'page': page,
'pageSize': '15',
'productName':'',
'conditionType': '1',
'applyname':'',
}
id_list=[] #存储企业的id
all_data_list=[]#存储所有的企业详细信息
json_ids=requests.post(url=url,headers=headers,data=data).json()
for dic in json_ids['list']:
id_list.append(dic['ID'])
#获取企业详情数据
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
for id in id_list:
data={
'id':id
}
detail_json=requests.post(url=post_url,headers=headers,data=data).json()
print(detail_json)
all_data_list.append(detail_json)
fp=open('./allData.json','a',encoding='utf-8')
json.dump(all_data_list,fp=fp,ensure_ascii=False)
print('end!!')
selenium
-
基于浏览器自动化的一个模块。
-
便捷的获取网站中动态加载的数据
-
便捷实现模拟登录
环境安装
pip install selenium
下载一个浏览器的驱动程序(谷歌浏览器)
- 下载路径:http://chromedriver.storage.googleapis.com/index.html
- 驱动程序和浏览器的映射关系:http://blog.csdn.net/huilan_same/article/details/51896672
- 实例化一个浏览器对象
- 编写基于浏览器自动化的操作代码
-发起请求:get(url)
-标签定位:find系列的方法
-标签交互:send_keys('xxx')
-执行js程序:excute_script('jsCode')
-前进,后退:back(),follow()
-关闭浏览器:quit()
-selenium处理iframe
-如果定位的标签存在于iframe标签之中,则必须使用switch_to.frame(id)
-动作链(拖动):from selenium.webdriver import ActionChains
- 实例化一个动作链对象:action=ActionChains(bro)
- 长按且点击
action.click_and_hold(div)
move_by_offset(x,y)
-让动作链立即执行:perform()
-释放动作链对象:action.release()
12306模拟登录
-超级鹰:http://www.chaojiying.com/
-12306模拟登录编码流程:
-使用selenium打开登录页面
-对当前selenium打开的这张页面进行截图
-对当前图片局部区域(验证码图片)进行裁剪
-好处:将验证码图片和模拟登录一一对应
-使用超级鹰识别验证码图片(返回坐标)
数据解析原理
-解析的局部文本内容都会在标签之间或者标签对应的属性中进行存储。
-进行指定标签的定位
-标签或者标签对应的属性中存储的数据值进行提取(解析)
#需求:爬取图片数据
import requests
if __name__=='__main__':
url='https://pic.qiushibaike.com/system/pictures/12405/124053508/medium/0Y1VC3QIIZDN8W32.jpg'
#content返回的是二进制形式的图片数据
#text(字符串) content(二进制) json(对象)
img_data=requests.get(url=url).content
with open('./qiutu.jpg','wb') as fp:
fp.write(img_data)
正则表达式
#需求:正则表达式爬取板块所有图片
import requests
import re
import os
if __name__ =='__main__':
#创建文件夹保存所有图片
if not os.path.exists('./qiutuLibs'):
os.mkdir('./qiutuLibs')
url = 'https://www.qiushibaike.com/imgrank/page/%d/'
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3861.400 QQBrowser/10.7.4313.400'
}
for pageNum in range(1,10):
#对应页码的Url
new_url=format(url%pageNum)
#使用通用爬虫对url对应的一整张页面进行爬取
page_text=requests.get(url=new_url,headers=headers).text
#使用聚焦爬虫将页面中所有的糗图进行解析和提取
ex='<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
img_src_list=re.findall(ex,page_text,re.S)
print(img_src_list)
for src in img_src_list:
#拼接出一个完整的图片url
src='https:'+src
#请求到了图片的二进制数据
img_data=requests.get(url=src,headers=headers).content
#生成图片名称
img_name=src.split('/')[-1]
#图片最终存储的路径
imgPath='./qiutuLibs/'+img_name
with open(imgPath,'wb',) as fp:
fp.write(img_data)
print(img_name,'下载成功!!!')
ba4
- 实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
- 通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
环境安装
-pip install bs4
-pip instal lxml
如何实例化BeautifulSoup对象
-from bs4 import BeautifulSoup
-对象实例化的两种形式:
1.将本地的Html文档中的数据加载到该对象中
fp=open(‘./test.html’,‘r’,encoding=‘utf-8’)
soup=BeautifulSoup(fp,‘lxml’)
2.将互联网上获取的页面源码加载到该对象中
page_text=response.text
soup=BeatufulSoup(page_text,‘html’)
-提供的用于数据解析的方法和属性:
- soup.tagName返回的是文档中第一次出现的tagName对应的标签
- soup.find():
-find(‘tagName’):等同于soup.div
-属性定位:
-soup.find(‘div’,class_/id/attr=‘song’)
-soup.find_all(‘tagName’):返回符合要求的所有标签(列表)
-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’]
Xpath
最常用且最便捷高效的一种解析方式。通用性强。
xpath解析原理
1.实例化一个etree的对象,且需将被解析的页面源码数据加载到该对象中。
2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的获取。
环境的安装
-pip install lxml
如何实例化一个etree对象
from lxml import etree
1.将本地的html文档中的源码数据加载到etree对象中:
etree.parse(filePath)
2.可以将从互联网上获取的源码数据加载到该对象中
etree.HTML(‘page_text’)
3.xpath(‘xpath表达式’):
/:表示的是从根节点开始定位。表示一个层级
//:表示的是多个层级。可以表示从任意位置开始定位
属性定位://div[@class=‘song’] tag[@attrName=‘attrValue’]
索引定位://div[@class=‘song’]/p[3] 索引是从1开始的
取文本:
/text():获取的是标签中直系的文本内容
//text():标签中非直系的文本内容
取属性:
/@attrName ==>img/src
实战代码
#需求:爬取58同城二手房中的房源信息
import requests
from lxml import etree
if __name__=='__main__':
#爬取到页面源码数据
url='https://bj.58.com/ershoufang/'
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36'
}
page_text=requests.get(url=url,headers=headers).text
#数据解析
tree=etree.HTML(page_text)
li_list=tree.xpath('//url[@class="house-list-wrap"]/li')
for li in li_list:
title=li.xpath('./li/div[2]/h2/a/text()')[0]
print(title)
fp.write(title+'\n')
#需求:爬取全国热门城市及所有城市
import requests
from lxml import etree
if __name__=='__main__':
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3861.400 QQBrowser/10.7.4313.400'
}
url='https://www.aqistudy.cn/historydata/'
page_text=requests.get(url=url,headers=headers).text
tree=etree.HTML(page_text)
#解析到热门城市和所有城市对应的a标签
#div/ul/li/a 热门城市a标签的层级关系
#div/ul/div[2]/li/a 全部城市a标签的层级关系
a_list=tree.xpath('//div[@class="bottom"]/ul/li/a | //div[@class="bottom"]/ul/div[2]/li/a ')
all_city_names = []
for a in a_list:
city_name=a.xpath('./text()')[0]
all_city_names.append(city_name)
print(all_city_names,len(all_city_names))