# 数据解析
参考文章:
爬虫
爬虫的分类
- 通用爬虫: 爬取整张网页数据
- 聚焦爬虫: 爬取部分数据
- 增量式爬虫: 监测网页更新部分数据
反爬机制
反反爬策略
robots, UA检测, UA伪装
http&https概念: 服务器和客户端进行数据交互的某种形式
常用的头信息:
- User-Agent:请求载体的身份
- Conntention: close
- Content-Type: json/text...
https 的加密方式:证书密钥加密
- 证书:是被应用在https的加密操作中的,该证书是有证书认证机构颁发的,证书中包含了公钥
requests:
get/post:
- url
- data/params: 对请求参数的封装,(data作用在post中,params作用在get方法中)
- headers:UA伪装
什么是动态加载的数据:由另一个额外的请求到的数据
- ajax
- js
如何鉴定页面中是否有动态加载的数据?
- 局部搜索
- 全局搜索
对一个陌生网站进行爬取前的第一步做什么?
- 确定你要爬取的数据是否为动态加载的
# 数据解析
解析: 根据指定的规则对数据进行提取
作用: 实现聚焦爬虫
聚焦爬虫的编码流程:
- 指定url
- 发起请求
- 获取相应数据
- 数据解析(在通用爬虫基础上多出来了数据解析)
- 持久化存储
数据解析的方式
- 正则解析
- bs4解析
- xpath解析
- pyquery(拓展)
数据解析的通用原理是什么?
- 数据解析需要作用在页面源码中(一组html标签组成的)
- html的核心作用是什么?
- 展示数据
- html是如何展示数据的?
- html所要展示的数据一定是被放置在html标签之中,或则在属性中
- 通用原理:
- 1.标签定位
- 2.取文本or取属性
# 正则实现的数据解析
需求: 爬取糗事百科中的糗图
如何爬取图片
# 方式二
from urllib import request
url = 'https://pic.qiushibaike.com/system/pictures/12217/122176466/medium/I844CD5W6MBJHYYG.jpg'
request.urlretrieve(url,'./456.jpg')
# urllib 就是一个比较老的网络请求的模块,在request模块没有出现之前,请求发送操作都是urllib
('./456.jpg', <http.client.HTTPMessage at 0x1839da405c0>)
import requests
# 方式一
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
url = 'https://pic.qiushibaike.com/system/pictures/12217/122176466/medium/I844CD5W6MBJHYYG.jpg'
img_data = requests.get(url=url,headers=headers).content # content 返回byte类型数据,因为图片是byte类型传输
with open('./123.jpg','wb') as f:
f.write(img_data)
# 方式1和方式2 对于图片数据爬取得操作最大得不同之处是在哪?
答:方式2不可以添加UA伪装机制
# 爬取糗事百科
import requests
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
url = 'https://www.qiushibaike.com/pic/'
page_text = requests.get(url, headers=headers).text
#分析数据图片都包含在如下得标签之中,那么我们使用正则来匹配出图片地址,注意有回车什么的,需要re.S
# <div class="thumb">
# <a href="/article/122176410" target="_blank">
# <img src="//pic.qiushibaike.com/system/pictures/12217/122176410/medium/KVN1L0WEZCF0MP26.jpg" alt="爱情">
# </a>
#</div>
dir_name = './qiushi'
import os
if not os.path.exists(dir_name):
os.mkdir(dir_name)
import re
ex = '<div class="thumb">.*?<img src="(.*?)" alt=.*?</div>'
img_src_list = re.findall(ex,page_text,re.S)
for src in img_src_list:
src = 'https:'+src
img_name = src.split('/')[-1]
img_path = dir_name+'/'+img_name
request.urlretrieve(src,img_path)
print(img_name,'下载成功')
I844CD5W6MBJHYYG.jpg 下载成功
EKOKK8LVTIR1N2MH.jpg 下载成功
...
# 爬取多页
- 分析:每一个页码对应的url是有共性:https://www.qiushibaike.com/pic/page/%d/
import requests
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
#分析出所有也页面的共性,只是page后的数字变化了
url = 'https://www.qiushibaike.com/pic/page/%d/'
dir_name = './qiushis'
import os
import re
if not os.path.exists(dir_name):
os.mkdir(dir_name)
for page in range(1,5):
# 拿出不同页码的url,进行页码的循环编写
new_text = requests.get(url%page, headers=headers).text
#正则匹配出img的src
ex = '<div class="thumb">.*?<img src="(.*?)" alt=.*?</div>'
img_src_list = re.findall(ex,new_text,re.S)
for src in img_src_list:
src = 'https:'+src
img_name = src.split('/')[-1]
img_path = dir_name+'/'+img_name
request.urlretrieve(src,img_path)
print(f'第{page}页下载成功')
第1页下载成功
第2页下载成功
第3页下载成功
第4页下载成功
# bs4解析
环境的环境
- pip install bs4
- pip install lxml
bs4 解析原理:BeautifulSoup是一个解析器
- 实例化一个BeautifulSoup对象, 并且将即将解析的页面源码数据加载到该对象中
- 调用BeautifulSoup对象中的相关属性和方法进行标签定位和数据提取
如何实例化BeautifulSoup对象那?
- 方式一: BeautifulSoup(fp,,'lxml') # fp通常是获得的一个文件句柄,这种方式专门用作解析本地存储的html文档中的数据
- 方式二: BeautifulSoup(page_text,'lxml') # 专门用作于将互联网上请求到的页面源码数据进行解析
# 假如我们有以下数据的页面源代码
<head>
<meta charset="UTF-8" />
<title>测试bs4</title>
</head>
<body>
<div>
<p>百里守约</p>
</div>
<div class="song">
<p>李清照</p>
<p>王安石</p>
<p>苏轼</p>
<p>柳宗元</p>
<a href="http://www.song.com/" title="赵匡胤" target="_self">
<span>this is span</span>
宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
<a href="" class="du">总为浮云能蔽日,长安不见使人愁</a>
<img src="http://www.baidu.com/meinv.jpg" alt="" />
</div>
<div class="tang">
<ul>
<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
<li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
<li><a href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
<li><a href="http://www.sina.com" class="du">杜甫</a></li>
<li><a href="http://www.dudu.com" class="du">杜牧</a></li>
<li><b>杜小月</b></li>
<li><i>度蜜月</i></li>
<li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>
</ul>
</div>
</body>
</html>
# 标签定位
soup.tagName: 定位到第一个TagName标签,返回的是单数
属性定位:soup.find('tagName',attrName='value'),返回也是一个单数
- fund_all:和find用法一致,但是返回值是一个复数
选择器定位:select('选择器'), 返回值是列表
- 标签、类、id、层级选择器(>:一个层级,空格表示多个层级)
# 提取数据
取文本:
- tag.string :获取标签中的直系的文本内容
- tag.text: 获取标签中所有文本内容,包括直系
取属性:
- tag['attrName']
# 方式一:要获得文件句柄
from bs4 import BeautifulSoup
fp = open('./test.html','r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml') # 将fp中的源码加载到soup对象中
#标签定位
soup.p #p>百里守约</p>,定位到第一个tagName标签
soup.find('div') #<div><p>百里守约</p></div> 也是返回第一个标签
soup.find('div',class_='song') # 返回<div class='song'> div中的内容,也是一个单数,可以通过class_、id等查找特定的标签
soup.find_all('div',class_='song') # find_all 和find用法一致,但是返回的是一个列表,也就是说find_all可能返回的是复数
# 选择器定位
soup.select('.tang') #选择带有.tang类的标签
soup.select('#feng') #选择id为feng的标签
#层级定位
soup.select('.tang > ul > li') # 放回的是tang类下ul下的所有li,返回一个列表
soup.select('.tang li') # 空格表示可以多个层级相隔,>表示一个层级相隔
[<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>,
<li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>,
<li><a alt="qi" href="http://www.126.com">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>,
<li><a class="du" href="http://www.sina.com">杜甫</a></li>,
<li><a class="du" href="http://www.dudu.com">杜牧</a></li>,
<li><b>杜小月</b></li>,
<li><i>度蜜月</i></li>,
<li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>]
# 取数据:定位标签就是为了去数据
li_6 = soup.select('.tang > ul > li')[6] #<li><i>度蜜月</i></li>
i_tag = li_6.i #去出li_6中的i标签
i_tag.text #'度蜜月'
i_tag.string #'度蜜月'
i_tag.strings.__next__() # '度蜜月' strings放回的是一个生成器
div = soup.find('div',class_='tang') # 如果我想要此div中的所有文本内容
div.text # 获得div中所有的文本,非直系,就是不是自己儿子辈的
div.string # 获取不到数据,因为div的儿子没有文本,直系
# 取属性
soup.find('a',id='feng')['href'] #'http://www.haha.com'
'http://www.haha.com'
# 爬取小说
- 爬取网站:http://www.shicimingju.com/book/sanguoyanyi.html
- 确认爬取的数据是否是动态加载的,显然不是
- 确认爬取数据:爬取章节名称和章节内容
- 在首页不仅要解析出章节名称,还有解析出章节rul
# 在首页中解析出章节名称&每一章节详细页url
url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
import requests
from bs4 import BeautifulSoup
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
page_text = requests.get(url,headers=headers).text #因为是文本,所以使用text、图片等要用content
soup = BeautifulSoup(page_text,'lxml')
# 分析可得:每个li标签中包含着每一章的rul,而直系内容就是每一章的名称啊,select的用法很旷阔
a_list = soup.select('.book-mulu > ul > li > a')
fp = open('sanguo.txt','w',encoding='utf-8')
for a in a_list:
detail_url = 'http://www.shicimingju.com' + a['href']
chap_title = a.string # 直系文本
# 对章节详情页的url发起请求,解析详情页中的章节内容,判断详情页没有动态加载的数据
detail_page_text = requests.get(detail_url,headers=headers).text
# 重新实例化soup
new_soup = BeautifulSoup(detail_page_text,'lxml')
# 找到放文本的div,列出所有的文本
chap_content = new_soup.find('div',class_='chapter_content').text
fp.write(chap_title+':'+chap_content+'\n')
print(chap_title,'爬取成功')
第一回·宴桃园豪杰三结义 斩黄巾英雄首立功 爬取成功
第二回·张翼德怒鞭督邮 何国舅谋诛宦竖 爬取成功
第三回·议温明董卓叱丁原 馈金珠李肃说吕布 爬取成功
第四回·废汉帝陈留践位 谋董贼孟德献刀 爬取成功
....
# xpath解析
环境的安装:pip install lxml
xpath的解析原理
- 实例化一个etree类型的对象,且将页面源码数据加载到该对象中
- 需要调用该对象的xpath方式结合着不同形式的xpath表达式进行标签定位和数据提取
etree 对象的实例化的两种方式:
- etree.parse(fileName) 将本地fileName文件加载成etree对象
- etree.HTML(page_text) 将网页上请求的数据加载成etree对象
etree对象的xpath方法返回的永远是一个列表
# 基于标签定位的xpath
- 在xpath表达式中最左侧的/表示含义是说,当前定位的标签必须从根节点开始进行定位,也就是说左侧只有一个/,则后面必须紧跟html
- xpath表达式中最左侧的//表示可以从任意位置进行标签定位
- xpath表达式中非最左侧的//表示的是多个层级跨越的意思
- xpath表达式中最左侧的/表示的是一个层级的意思
from lxml import etree
tree = etree.parse('./test.html')
#将一个文本内容加载成etree对象后,我们就可以调用对象的xpath函数,通过树状结构层级查找元素标签
tree.xpath('/html/head/meta') #[<Element meta at 0x290d200e448>] ---> 绝对路径查找,
#通过索引取出对应的对象
tree.xpath('/html/head/meta')[0] #<Element meta at 0x290d1f623c8>
tree.xpath('//meta')[0] #<Element meta at 0x290d1cb3dc8> ----> 相对路径查找,将整个页面源码中所有的meta进行定位 //表示
tree.xpath('/html//meta')[0] #<Element meta at 0x290d19dff08>
<Element meta at 0x290d19dff08>
# 基于属性定位的xpath
属性定位: //tagName[@arrtName='value']
索引定位: //tagName/li[3]
tree.xpath('//div') #同时列出三个对象 [<Element div at 0x290d1954248>,[<Element div at 0x290d1954248>],[<Element div at 0x290d1954248>]]
#属性定位
tree.xpath('//div[@class="song"]') # [<Element div at 0x290d1954248>] 列出满足class=song的div
# 索引定位
tree.xpath('//div[@class="tang"]/ul/li') # 列表中多个对象
tree.xpath('//div[@class="tang"]/ul/li[1]') # 1写在里面表示第一个,从1开始计数
tree.xpath('//div[@class="tang"]/ul/li')[0]
[<Element li at 0x290d21c2188>]
# 提取数据
取文本:
- /text(): 取直系的文本内容
- //text(): 取所有的文本内容
取属性:
- tag/@attrName: tag是我们匹配到的标签,通过@方式取值
# 取文本
tree.xpath('//p[1]/text()') # 取出每个div的第一个p标签的文本
tree.xpath('//p[1]') #[<Element p at 0x290d2213d08>, <Element p at 0x290d20a6ac8>]
tree.xpath('//div[@class="song"]//text()') # 取出div下所有文本
['\n\t\t',
'李清照',
'\n\t\t',
'王安石',
'\n\t\t',
'苏轼',
'\n\t\t',
'柳宗元',
'\n\t\t',
'\n\t\t\t',
'this is span',
'\n\t\t宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱',
'\n\t\t',
'总为浮云能蔽日,长安不见使人愁',
'\n\t\t',
'\n\t']
#取属性
tree.xpath('//a[@id="feng"]/@href') # 先根据属性查出对象,再通过@符号取值
tree.xpath('//a[@title="赵匡胤"]/@href') #['http://www.song.com/']
['http://www.song.com/']
# 爬取boss的招聘信息
- 岗位名称
- 公司名称
- 薪资
- 岗位描述
import requests
from bs4 import BeautifulSoup
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
# 如果获取的page_text中的数据不是正常的response数据,且在爬取之前访问过该网址,则可能记录 cookie,所以必须携带cookie访问
'cookie':'lastCity=101010100; __c=1566901179; __g=-; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1566901179; _uab_collina=156690117919419065884495; __l=l=%2Fwww.zhipin.com%2F&r=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dhn6W0tys1Ol5M08yMufJbxta0Zk092ycaDfmbIEUjJwy4tlSJ2O_qQvMIExRX8ps%26wd%3D%26eqid%3Dbc612faf000e4860000000025d6503b9&friend_source=0&friend_source=0; __zp_stoken__=91d9QItKEtUk5dMMnDG7lwzq8sVSYJawCtdfoOUdRiRv7yPRrk5R5sa3VrzsQn9ZL47h1%2FWTcrObgrgz4DnfBb0DxA%3D%3D; __a=93010145.1566901179..1566901179.3.1.3.3; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1566901385'
}
url = 'https://www.zhipin.com/job_detail/?query=%E7%88%AC%E8%99%AB&city=101010100&industry=&position='
page_text = requests.get(url, headers=headers).text
tree = etree.HTML(page_text) # 这里获取的是网页上传来的text,所以使用HTML
# # xpath 返回的每一个对象也是及继承了tree的,所以也有xpath的方法
li_list = tree.xpath('//div[@class="job-list"]/ul/li')
for li in li_list:
#li也有xpath的方法,需要将li表示的局部页面源码数据进行提取
# 如果xpath表达式被作用在了循环中,表达式要以./或者.//开头
detail_url ='https://www.zhipin.com'+ li.xpath('.//div[@class="info-primary"]/h3/a/@href')[0] #注意子对象li,要匹配本身的内容就的以.//开始
job_title = li.xpath('.//div[@class="info-primary"]/h3/a/div/text()')[0]
salary = li.xpath('.//div[@class="info-primary"]/h3/a/span/text()')[0]
company = li.xpath('.//div[@class="info-company"]/div/h3/a/text()')[0]
#对详情页的url发请求解析出岗位描述
detail_page_text = requests.get(detail_url,headers=headers).text
new_tree = etree.HTML(detail_page_text)
job_desc = new_tree.xpath('//div[@class="text"]//text()')
job_desc = ''.join(job_desc)
print(job_title,job_desc,company,salary)
爬虫工程师
岗位职责:1、负责公司的爬虫核心技术研究以及爬虫策略优化;2、根据业务需求,实现大规模文本、图片、视频数据抓取、清洗、存储等工作;3、对数据质量负责,提供数据分析报告,优化数据应用架构,支持产品研发。岗位要求:1、计算机、数学或统计等相关专业本科及以上学历,2年以上数据相关工作经验;2、熟悉linux平台,掌握Python/JAVA或某种编程语言;3、熟悉基于正则表达式、CSS、http协议、ml等的网页信息抽取技术;4、精通常用的爬虫技术及架构,并能快速实现;5、熟悉多线程编程、分布式计算,有分布式系统使用经验。6、具备良好的编程习惯和算法基础,具有钻研精神;7、对数据驱动业务有深入理解,对数据与业务方面有足够的敏感性,独立思考能力和逻辑分析能力强。
汽车之家(NYSE:ATHM)成立于2005年,是中国领先的汽车互联网平台——为汽车消费者提供选车、买车、用车、换车等所有环节的全面、准确、快捷的一站式服务。我们致力于通过产品服务、数据技术、生态规则和资源为用户和客户赋能,建设“车媒体、车电商、车金融、车
# 另一种较为通用的xpath表达式的使用形式
爬取糗事百科的段子内容和作者名称,找一个有匿名用户发表文字的网页url
- 遇到匿名用户时,由于没有了a标签,会发生报错,我们必须进行处理
- 使用 '|' 或在在div中对多个条件进行筛选,判断,用于解析不规则布局的页面
- 遇到匿名用户时,由于没有了a标签,会发生报错,我们必须进行处理
url= 'https://www.qiushibaike.com/text/page/2/'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}
from lxml import etree
page_text = requests.get(url,headers=headers).text
page_text
tree = etree.HTML(page_text)
#发现每个文字内容都在这个div中
div_list = tree.xpath('//div[@id="content-left"]/div')
for div in div_list:
#当解析到匿名用户是,结构发生裱花没有a标签会报错out of range,必须处理匿名用户的情况使用管道符处理匿名情况的情况,或者叫或关系匹配
author = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()')[0]
content_list = div.xpath('.//div[@class="content"]/span//text()')
content = ''.join(content_list)
print(author,content_list)
十亿精兵总统领
['\n\n\n连载小插曲', '小时候村里的孩子多,又没啥可玩的,个个都是淘气包,到谁家,谁家大人都头疼,多少都会搞点破坏,所以家长们统一口径,要玩就出去玩,不准到家里玩!', '这不就到了一年一度的寒假期间,小伙伴们早早写好了作业,就等着撒欢玩。', '终于机会来了,天下起了鹅毛大雪,我们相约去打雪仗,从村东头打到村西头,又从西头打到东头,打来打去感觉有点枯燥了,天也有点黑了,就有人提议我们去堆个大雪人吧,大家都表示同意,可去哪里堆是个问题。', '这时候村长家的公子歌歌哒说,我们去大队部吧,那里面地方大。有领导的孩子带头,\n…\n', '查看全文']
...
爆笑菌boy
['\n\n\n老婆出差,我给老婆发短信:宝贝,发张私密照呗!一分钟不到,收到一张照片,老婆一丝不挂,左手付墙,右手撩头发。整个照片画面和谐,可我就感到有那么一点不对,又说不上来呢……\n\n']
匿名用户 ['\n\n\n为啥现在感觉对象亲我,就想小鸡啄米呢\n\n']
# 解决中文乱码问题
爬取彼岸图网,对应的url:http://pic.netbian.com/4kmeishi/
获取图片和相应的名称
分析: 第一页url:http://pic.netbian.com/4kmeishi/ 其他页网页:http://pic.netbian.com/4kmeishi/index_2.html 页码改变
# 制定的通用的url模板
url = 'http://pic.netbian.com/4kmeishi/index_%d.html'
for page in range(1, 6):
if page == 1:
new_url = 'http://pic.netbian.com/4kmeishi/'
else:
new_url = url%page
page_text = requests.get(new_url,headers=headers).text
# print(page_text) # 打印源码,发现文字乱码,并且这里使用response.encoding = 'utf-8'不能解决问题
tree = etree.HTML(page_text)
li_list = tree.xpath('//*[@id="main"]/div[3]/ul/li')
for li in li_list:
img_src = 'http://pic.netbian.com'+li.xpath('./a/img/@src')[0]
img_name = li.xpath('./a/b/text()')[0]
img_name = img_name.encode('iso-8859-1').decode('gbk') #iso-8859-1是一个字符集,但是比utf8更多包括的字符
print(img_src, img_name)
http://pic.netbian.com/uploads/allimg/181223/205433-154556967383ec.jpg 2019新年快乐 丰盛美食
http://pic.netbian.com/uploads/allimg/180726/192028-153260402827c6.jpg 健康的水果和蔬菜4k壁纸
http://pic.netbian.com/uploads/allimg/171226/100652-1514254012c82a.jpg 猕猴桃,水果,蔬菜沙拉,西
http://pic.netbian.com/uploads/allimg/171219/191722-15136822427df2.jpg 松饼,甜点,薄荷,5k图片
http://pic.netbian.com/uploads/allimg/171212/195515-1513079715ce91.jpg 早餐麦片,牛奶,水果,草莓
http://pic.netbian.com/uploads/allimg/171212/185016-15130758160ca1.jpg 意大利烤宽面条4k美食壁
...
# 爬取站长素材的高清图片,并保存到本地,url:http://sc.chinaz.com/tag_tupian/YaZhouMeiNv.html
import requests,os
from bs4 import BeautifulSoup
from lxml import etree
url = 'http://sc.chinaz.com/tag_tupian/YaZhouMeiNv.html'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}
page_text = requests.get(url, headers=headers).text
tree = etree.HTML(page_text)
img_list = tree.xpath('//div[@id="container"]/div')
dir_name = 'meinv'
if not os.path.exists(dir_name):
os.mkdir(dir_name)
for img in img_list:
img_info = img.xpath('./p/a/text()')[0]
img_info= img_info.encode('iso-8859-1').decode('utf-8')
detail_img = img.xpath('./p/a/@href')[0]
new_page = requests.get(detail_img,headers=headers).text
new_tree = etree.HTML(new_page)
img_url = new_tree.xpath('//div[@class="down_wrap"]//div[@class="imga"]/a/@href')[0]
img_name = img_url.split('/')[-1]
file_path = dir_name +'/'+ img_name
fp = open(file_path,'wb')
file = requests.get(img_url,headers=headers).content
fp.write(file)
fp.close()
# 爬取站长获取模板,url:http://sc.chinaz.com/jianli/free.html?qq-pf-to=pcqq.c2c
import requests
import re
from lxml import etree
import random
from bs4 import BeautifulSoup
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}
url = 'http://sc.chinaz.com/jianli/free_%d.html'
dir_name = 'moban'
if not os.path.exists(dir_name):
os.mkdir(dir_name)
for page in range(1, 6):
if page == 1:
new_url = 'http://sc.chinaz.com/jianli/free.html'
else:
new_url = url%page
page_text = requests.get(new_url,headers=headers).text
tree = etree.HTML(page_text)
m_list = tree.xpath('//div[@id="container"]/div')
for m in m_list:
detail_htm = m.xpath('./a/@href')[0]
m_name = m.xpath('./a/img/@alt')[0]
m_name = m_name.encode('iso-8859-1').decode('utf-8')
# 跨页面
detail_page = requests.get(detail_htm,headers=headers).text
new_tree = etree.HTML(detail_page)
li_list = new_tree.xpath('//div[@id="down"]/div[2]/ul/li')
num = random.randint(0,len(li_list)-1)
new_li = li_list[num]
new_url = new_li.xpath('./a/@href')[0]
if "src=" in new_url:
xxx = re.findall('(jianli[\d]+)',new_url)
new_url = f'http://downsc.chinaz.net/Files/DownLoad/jianli/201908/{xxx[0]}.rar'
filename = dir_name+'/'+m_name+'.rar'
data = requests.get(new_url,headers=headers).content
with open(filename,'wb') as f:
f.write(data)
print(f'第{page}页抓取成功!')
第1页抓取成功!
第2页抓取成功!
第3页抓取成功!
第4页抓取成功!
第5页抓取成功!
← requests知识进阶 多任务协程爬虫 →