# 数据解析

参考文章

  • 爬虫

  • 爬虫的分类

    • 通用爬虫: 爬取整张网页数据
    • 聚焦爬虫: 爬取部分数据
    • 增量式爬虫: 监测网页更新部分数据
  • 反爬机制

  • 反反爬策略

  • 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中对多个条件进行筛选,判断,用于解析不规则布局的页面
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页抓取成功!