爬虫 解析数据

""""
反爬机制:门户网站,可以通过制定相应的策略或者技术手段,防止爬虫程序进行网站数据的爬取。
反反爬策略:爬虫程序可以通过制定相关的策略或者技术手段,破解门户网站中具备的反爬机制,从而可以获取门户网站中相关的数据。
robots.txt协议:君子协议。规定了网站中哪些数据可以被爬虫爬取哪些数据不可以被爬取。
"""

from urllib.request import urlopen  # 来自 网页模块.请求 导入 网页打开

url = "http://www.baidu.com"

resp = urlopen(url)
print(resp)  # <http.client.HTTPResponse object at 0x000002814508BFD0>
print(resp.read())  # 此时拿到的是页面源代码 (b' 二进制)
print(resp.read().decode("utf-8"))  # 此时拿到的是页面源代码 (UTF-8模式)
# ctrl+f 搜索:charset ,确定转化成 utf-8 , GBK       搜索结果:charset=utf-8

# 源代码:html , css ,js

with open("mybaid.html", mode="w", encoding="utf-8") as f:  # 创建文件.html格式  写 UTF-8模式
	f.write(resp.read().decode("utf-8"))     # 写的内容:读取resp   以UTF-8模式写入
	# 细节:打开写入的文件 "mybaidu.html",以浏览器或者别的方式打开,你就能看到网站模式。
		# 如果直接print,只能看到源代码。必须写出来才行~
		# 你可以下写入的网站上进行修改,都可以。哈哈~~恶作剧啥的


//***** requests 测试

import requests

# 爬取百度的页面源代码
url = "http://www.baidu.com"
resp = requests.get(url)
resp.encoding = "utf-8"
print(resp)   # <Response [200]>
print(resp.text)  # 拿到页面源代码



//****************   get 请求

import requests

content = input('请输入你要检索的内容:')
url = f"https://www.sogou.com/web?query={content}"

headers = {
	# 添加一个请求头信息. UA
	"User-Agent": " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
# 处理一个小小的反爬     细节:这是字典
resp = requests.get(url, headers=headers)
print(resp.text)

print(resp.request.headers)  # 可以查看到请求头信息
		# {'User-Agent': 'Mozilla/5.0 xxxx', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
	 # 你会发现,就是我们写入的请求头

//******
# 如果不写:headers 的话,默认的 python 的 requests 的请求头信息是什么呢?
resp = requests.get(url)
print(resp.request.headers)   # python-requests/2.31.0  这时默认的。所以,服务器会识别出来。
		# {'User-Agent': 'python-requests/2.31.0', ......}
		# {'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Cookie': 'ABTEST=0|1703085357|v17; SNUID=658039558B8C8778FE4F23738BB63A7E; IPLOC=CN5000; SUID=EF0AB2DE2431A40A000000006583052D; cuid=AAHKKmo+SQAAAAqgKmxzkgAAEAM='}



//*********************   post 请求

import requests
import json
url = "https://fanyi.baidu.com/sug"

hehe = {
	"kw": input("请输入一个单词")
}

resp = requests.post(url, data=hehe)

print(resp.text)  # 拿到的是文本字符串
				# {"errno":0,"data":[{"k":"Apple","v":"n. \u82f9\u679c\u516c\u53f8\uff0c\u539f\u79f0\u82f9\u679c\u7535\u8111\u516c\u53f8"},{"k":"apple","v":"n. \u82f9\u679c; \u82f9\u679c\u516c\u53f8; \u82f9\u679c\u6811"},{"k":"APPLE","v":"n. \u82f9\u679c"},{"k":"apples","v":"n. \u82f9\u679c\uff0c\u82f9\u679c\u6811( apple\u7684\u540d\u8bcd\u590d\u6570 ); .....}
print(resp.json())  # 此时拿到的直接是json数据   (字典)
				# {'errno': 0, 'data': [{'k': 'Apple', 'v': 'n. 苹果公司,原称苹果电脑公司'}, {'k': 'apple', 'v': 'n. 苹果; 苹果公司; 苹果树'}, {'k': 'APPLE', 'v': 'n. 苹果'}, {'k': 'apples', 'v': 'n. 苹果,苹果树( apple的名词复数 ); [美国口语]棒球; [美国英语][保龄球]坏球; '}, {'k': 'Apples', 'v': '[地名] [瑞士] 阿
print(resp.json()['data'])  # 拿到的就是'data' 的value

//***********************

import requests

url = "https://movie.douban.com/j/chart/top_list"

hehe = "type=13&interval_id=100%3A90&action=&start=0&limit=20"

resp = requests.get(url,hehe)  # 处理一个小小的反爬
print(resp.text)   # 会发现,什么都没有!!  那就是:检测设备。那就反爬


"""""
	说明一下 parse 
hehe = {
	"type": "13",
	"interval_id": "100:90",
	"action": "",
	"start": "0",
	"limit": "20"
}
params=hehe 等价于 hehe = "type=13&interval_id=100%3A90&action=&start=0&limit=20"
# 你可理解成: parse 相当于 把字典拼(:)接成(=)形式
  所以,我们就写成字典方式
"""""

import requests

url = "https://movie.douban.com/j/chart/top_list"

hehe = {
	"type": "13",
	"interval_id": "100:90",
	"action": "",
	"start": "0",
	"limit": "20"
}

headers = {
	"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"
}


resp = requests.get(url, params=hehe, headers=headers)  # 处理一个小小的反爬              你看这下面:\/view\/photo\/s_ratio_poster\  明显有问题。把网站换个样式了
print(resp.text)   # [{"rating":["9.6","50"],"rank":1,"cover_url":"https://img1.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p2561716440.jpg" .....
print(resp.json())   # [{'rating': ['9.6', '50'], 'rank': 1, 'cover_url': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2561716440.jpg', ...
													# 通过 json()就把网址正确输出了   以后json()也用一下吧,觉得。
print(resp.request.url)   # https://movie.douban.com/j/chart/top_list?type=13&interval_id=100%3A90&action=&start=0&limit=20
print(resp.request)     # <PreparedRequest [GET]>
							# 细节: 请求的时候requests会自动拼接带'?'    不用写成 (url, '?',params=hehe) 这种形式


//*************  正则表达式
import re

result = re.findall("a", "我是一个abcdeafg")
print(result)   # ['a', 'a']

result = re.findall(r"\d+", "我今年18岁, 我有200000000块")
print(result)   # ['18', '200000000']


# 这个是重点. 多多练习   效率高
result = re.finditer(r"\d+", "我今年18岁, 我有200000000块")
print(result)   # <callable_iterator object at 0x000001E02B3BAA70>
for item in result:  # 从迭代器中拿到内容
	print(item)    # <re.Match object; span=(3, 5), match='18'>  ** <re.Match object; span=(10, 19), match='200000000'>
	print(item.group())  # 18    从匹配到的结果中拿到数据            ** 200000000


# search只会匹配到第一次匹配的内容
result = re.search(r"\d+", "我叫周杰伦, 今年32岁, 我的班级是5年4班")
print(result)  # <re.Match object; span=(9, 11), match='32'>
print(result.group())  # 32


# match, 在匹配的时候. 是从字符串的开头进行匹配的, 类似在正则前面加上了^\d
result = re.match(r"\d+", "666叫88周杰伦, 今年32岁, 我的班级是5年4班")
print(result)   # <re.Match object; span=(0, 3), match='666'>
print(result.group())   # 666   必须是开头开始

result = re.match(r"\d+", "叫88周杰伦, 今年32岁, 我的班级是5年4班")
print(result)   # None
print(result.group())   # 报错的!!!

# 预加载, 提前把正则对象加载完毕
obj = re.compile(r"\d+")
# 直接把加载好的正则进行使用
result = obj.findall("我叫周杰伦, 今年32岁, 我的班级是5年4班")   #分开加载:re 和 数据
print(result)   # ['32', '5', '4']



# 想要提取数据必须用小括号括起来. 可以单独起名字
# (?P<名字>正则)
# 提取数据的时候. 需要group("名字")
s = """
<div class='西游记'><span id='10010'>中国联通</span></div>
<div class='西游记'><span id='10086'>中国移动</span></div>
"""
obj = re.compile(r"<span id='\d+'>.*?</span>")
result = obj.findall(s)    # ["<span id='10010'>中国联通</span>", "<span id='10086'>中国移动</span>"]

obj = re.compile(r"<span id='(\d+)'>(.*?)</span>")
result = obj.findall(s)    # [('10010', '中国联通'), ('10086', '中国移动')]


obj = re.compile(r"<span id='(?P<id>.*?)'>(?P<name>.*?)</span>")
result = obj.finditer(s)
print(result)   # obj = re.compile(r"<span id='(?P<id>\d+)'>(?P<name>.*?)</span>")   迭代器
for item in result:
	id = item.group("id")   # 必须是 "id" 或者 "name"
	print(id)		# 10010  **  10086
	name = item.group("name")
	print(name)		# 中国联通   **  中国移动

//*****************************    豆瓣
import requests
import re

f = open("豆瓣250电影.csv", mode="w", encoding='utf-8')
url = "https://movie.douban.com/top250?start=200&filter="

headers = {
	"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"
}

resp = requests.get(url)   # <Response [418]>    反爬机制  headers 解决
resp = requests.get(url, headers=headers)
# resp.encoding = 'utf-8'  # 解决乱码问题.
pageSource = resp.text

# 编写正则表达式   r'xxxxxx'  用单引号,避免跟""冲突
# re.S 可以让正则中的.匹配换行符  (让.也涵盖换行)   指定re规则
obj = re.compile(r'<div class="item">.*?<span class="title">(?P<name>.*?)</sp'
				 r'an>.*?导演: (?P<dao>.*?)&nbsp;.*?<br>'
				 r'(?P<year>.*?)&nbsp;.*?<span class="rating_num" property="v:average">'
				 r'(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价</span>', re.S)

# 进行正则匹配   通过这个制定的re规则,来处理 resp.text数据
result = obj.finditer(pageSource)
for item in result:
	name = item.group("name")
	dao = item.group("dao")
	year = item.group("year").strip()  # 去掉字符串左右两端的空白  空格----1949,位置在最前面。随意会有空格。输出的时候屏蔽掉
	score = item.group("score")
	num = item.group("num")
	f.write(f"{name},{dao},{year},{score},{num}\n")  # 如果觉着low. 可以更换成csv模块. 进行数据写入

f.close()
resp.close()
print("豆瓣TOP250提取完毕.")


//*****************  自己写的    取了特有部分,+1+1+1
import re

import requests

url = "https://movie.douban.com/top250?start=0&filter="
headers = {
	"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
resp = requests.get(url,headers=headers)
resp.encoding="utf-8"
# print(resp.text)
w=1
while w <25:
	p=str(w)
	obj=re.compile(r'<em class="">'+p+'</em>.*?<span class="title">(?P<name>.*?)</span>.*?导演: '
				   r'(?P<daoyan>.*?);&nbsp.*?v:average">(?P<score>.*?)</span>.*?<span>(?P<num>.*?</span>)',re.S)
	result=obj.finditer(resp.text)
	for item in result:
		name=item.group("name")
		score=item.group("score")
		daoyan=item.group("daoyan")
		num=item.group("num")
		print(name,daoyan,score,num)
	w=w+1

//**************************  循环列表
# 如何翻页提取?
# (页数 - 1)*25  => start
import requests
import re
f = open("豆瓣250电影.csv", mode="w", encoding='utf-8')

i=-25
while i<250:
	url = "https://movie.douban.com/top250?start="+str(i+25)+"&filter="
	headers = {
		"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"
	}

	resp = requests.get(url)
	resp = requests.get(url, headers=headers)

	pageSource = resp.text
	obj = re.compile(r'<div class="item">.*?<span class="title">(?P<name>.*?)</sp'
					 r'an>.*?导演: (?P<dao>.*?)&nbsp;.*?<br>'
					 r'(?P<year>.*?)&nbsp;.*?<span class="rating_num" property="v:average">'
					 r'(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价</span>', re.S)

	# 进行正则匹配
	result = obj.finditer(pageSource)
	for item in result:
		name = item.group("name")
		dao = item.group("dao")
		year = item.group("year").strip()  # 去掉字符串左右两端的空白  空格----1949,位置在最前面。随意会有空格。输出的时候屏蔽掉
		score = item.group("score")
		num = item.group("num")
		f.write(f"{name},{dao},{year},{score},{num}\n")  # 如果觉着low. 可以更换成csv模块. 进行数据写入
	i=i+25    #细节:这个不在for循环里
f.close()  # 退出 while 循环,才关闭!!
resp.close()    # 退出 while 循环,才关闭!!
print("豆瓣TOP250提取10页数据完毕.")

//**********  获取电影天堂 电影信息
"""""
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>
	<a href="https://blog.csdn.net/rassamqi?spm=1011.2124.3001.5343">麦合学长</a>

</body>
</html>
"""""  # <a> ------- </a> 这是一个结构     <a href="xxxx"> 麦合学长 </a>   页面:出现字,点击就是xxxx连接

"""
1. 提取到主页面中的每一个电影的背后的那个url地址
	1. 拿到 "2021必看热片" 那一块的HTML代码.
	2. 从刚才拿到的HTML代码中提取到href的值

2. 访问子页面, 提取到电影的名称以及下载地址
	1. 拿到子页面的页面源代码
	2. 数据提取
"""
import requests
import re
f = open("电影天堂.csv", mode="w", encoding='utf-8')

url = "https://www.dy2018.com/"
resp = requests.get(url)
resp.encoding = "gbk"   # 源代码 charset 是GBK (国内网站,不是GBK,就是UTF-8)
# print(resp.text)   判断一下有没有正常输出


# 1.提取2021必看热片部分的HTML代码
obj1 = re.compile(r"2023必看热片.*?<ul>(?P<html>.*?)</ul>", re.S)
result1 = obj1.search(resp.text)
html = result1.group("html")

# 2.提取a标签中的href的值
obj2 = re.compile(r"<li><a href='(?P<href>.*?)' title")

result2 = obj2.finditer(html)   # 细节:从html里面进行进一步判断
										# 细节:截取信息,可以从 id class 等入手
obj3 = re.compile(r'<div id="Zoom">.*?◎片  名(?P<movie>.*?)<br />.*?<td style="WORD-WRAP: break-word"'
				  r' bgcolor="#fdfddf"><a href="(?P<download>.*?)">', re.S)   # 正则工具准备好
for item in result2:
	# print(item.group("href"))   肯定不行,必须拼接
	# 拼接出子页面的url
	child_url = url.strip("/") + item.group("href")   # 细节:别忘了删掉后面的"/" 。因为多余了
	child_resp = requests.get(child_url)
	child_resp.encoding = 'gbk'

	result3 = obj3.search(child_resp.text)   # 用obj3工具,对数据text进行修改   一个html只有一个数据,所以可以用 search
	movie = result3.group("movie")
	download = result3.group("download")
	print(movie, download)
	f.write(f"{movie},{download}\n")
f.close()  # 退出 while 循环,才关闭!!
resp.close()    # 退出 while 循环,才关闭!!
print("电影天堂数据爬取完毕.")

//*******  细节补充
# 爬虫过程中,突然出现,无法爬取。刚开始的 print(resp.text) 就不行
# 原因:因为,该网站偶尔检测到这时非浏览器行为,检测到了设备
# 两种办法:1.加请求头 headers
# 2.过一会儿再试一试,会好的
# 如果爬虫量大----> 会导致网站挂掉。可能网站会拉黑你的ip。所以,不要爬虫太狠~~

//************** 自己写的
import re

import requests


url="https://www.1905.com/vod/?id=1"
headers={
	"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
resp=requests.get(url,headers=headers)
resp.encoding="utf-8"
# print(resp.text)

obj1=re.compile(r'title="欧美">欧美</a>(?P<html>.*?)title="内地">',re.S)
rusult=obj1.search(resp.text)
html=rusult.group("html")
# print(html)
obj2=re.compile(r'<a href="(?P<name>.*?)" target="')
obj3=re.compile(r'<span id="playerBoxIntroCon">(?P<xinxi>.*?)<a href=')
# 第二部,在网站内部,获取电影的信息

headers1={
	"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
result2=obj2.finditer(html)
for item in result2:
	# print(item.group("name"))
	resp2=requests.get(item.group("name"))
	resp.encoding="utf-8"
	# print(resp2)
	result3=resp.text
	result4=obj3.search(result3)
	try:
		xinxi=result4.group("xinxi")
		print(xinxi)
	except AttributeError as e:
		print(e)
		pass

												# 程序没问题!!
//**********************   html 简单入门
"""""
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>我是标题</title>
	</head>
	<body bgcolor="pink">
		<h1 align="right">我爱周润发</h1>
		<p>周润发同志. 曾经是一个赌神. 我特别崇拜他</p>
		<a href="http://www.baidu.com">周润发的个人主页</a>
		<img src="abc.jpg" width="50px" height="60px"/>
	</body>
</html>

<!--
html基本语法:
   1. <标签名 属性="值">被标记的内容</标签名>
   2. <标签名 属性="值" />
 -->
"""""
"""""
//****************   ChildProcessError<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
	<link rel="stylesheet" href="mycss.css">
	<style>
		span{
			color: pink;
		}
	</style>
</head>
<body>
	<div style="width:100px;height:100px;border: 1px solid red;">你好, 我叫周润发</div>
	<span>我爱黎明</span>
</body>
</html>
"""""
# //****** CSS 选择器   自己去源代码看吧。我弄过来,好多乱码

//*************  bs4

# 安装bs4
# pip install bs4
from bs4 import BeautifulSoup

html = """
<ul>
	<li><a href="zhangwuji.com">张无忌</a></li>
	<li id="abc"><a href="zhouxingchi.com">周星驰</a></li>
	<li><a href="zhubajie.com">猪八戒</a></li>
	<li><a href="wuzetian.com">武则天</a></li>
	<a href="jinmaoshiwang.com">金毛狮王</a>        # 这个就拿不到了
</ul>
"""

# 1. 初始化BeautifulSoup对象
page = BeautifulSoup(html, "html.parser")   # 解析(parser)
# page.find("标签名", attrs={"属性": "值"})  # 查找某个元素, 只会找到一个结果
# page.find_all("标签名", attrs={"属性": "值"})  # 找到所有结果

li = page.find("li", attrs={"id":"abc"})
print(li)   # <li id="abc"><a href="zhouxingchi.com">周星驰</a></li>
					# li 标签里面,还有 a 标签
a = li.find("a")    # 只有一个标签,不用属性都可以
print(a.text)  # 拿文本   周星驰
print(a.get("href"))  # 拿属性. get("属性名")   zhouxingchi.com


li_list = page.find_all("li")  # 所有 li 标签
for li in li_list:
	a = li.find("a")
	text = a.text      # 张无忌
	href = a.get("href")    # zhangwuji.com
	print(text, href)   # 张无忌 zhangwuji.com
						# 周星驰 zhouxingchi.com
						# 猪八戒 zhubajie.com
						# 武则天 wuzetian.com

//**************  bs4 实战    北京新发地   自己写的
import requests

f=open("北京新发地价格表.text",mode="w",encoding="utf-8")
url = 'http://www.xinfadi.com.cn/getPriceData.html'
t=1
while t<30:

	body = {
		'limit': 20,
		'current':t   # 页数
	}
	res = requests.post(url, data=body)
	r=res.json()["list"]
	# print(res.json()["list"])
	# print(res.text)
	for item in r:
		id=item["id"]
		prodName= item["prodName"]
		lowPrice = item["lowPrice"]
		highPrice = item["highPrice"]
		avgPrice = item["avgPrice"]
		place = item["place"]
		pubDate = item["pubDate"]
		# print(id,prodName,lowPrice,highPrice,avgPrice,place,pubDate)
		f.write(f"编号:{id},产品名:{prodName},最低价{lowPrice},最高价{highPrice},平均价{avgPrice},产地{place},产出时间{pubDate}\n")
		# f.write(id,prodName,lowPrice,highPrice,avgPrice,place,pubDate)
		print("正在爬虫.....")
	t=t+1
print("爬虫结束")

//******************  老师的代码  北京新发地

import requests
from bs4 import BeautifulSoup

f = open("新发地菜价.csv", mode="w", encoding='utf-8')

url = "http://www.xinfadi.com.cn/marketanalysis/0/list/1.shtml"
resp = requests.get(url)
# 初始化BS4对象
page = BeautifulSoup(resp.text, "html.parser")
table = page.find("table", attrs={"class": "hq_table"})   # 细节:我只要找到一个地方就行
trs = table.find_all("tr")[1:]   # 此时拿到除了第一行外的所有tr 标签  具体情况,具体分析
for tr in trs:  # 每一行
	tds = tr.find_all("td")   # 在找到 tr 里面的 td 标签
	name = tds[0].text    # 找到文本内容
	low = tds[1].text
	avg = tds[2].text
	hig = tds[3].text
	kind = tds[4].text
	dan = tds[5].text
	date = tds[6].text
	# print(name, low, avg, hig, kind, dan, date)
	f.write(f"{name},{low},{avg},{hig},{kind},{dan},{date}\n")   # 太好用了这方法
f.close()
resp.close()
print("爬取成功")


# 核心:处理tr  td 模式   <tr class=.... <td 属性 >值1/文本1</td><td 属性 >值2/文本2</td>....></tr>
#  实际上:<tr class=.... <td 属性 >值1/文本1</td><td 属性 >值2/文本2</td>....></tr><tr class=.... <td 属性 >值1/文本1</td><td 属性 >值2/文本2</td>....></tr>
# 就这样连着的    tr 行  / td  列

//**************   哈哈哈 12.23  半夜不睡觉,下载美女图片哈哈
import requests
from bs4 import BeautifulSoup
import re

url = "https://www.umei.net"

# doman = "https://www.umei.net/bizhitupian/xiaoqingxinbizhi/"
resp = requests.get(url)
resp.encoding = "utf-8"

n = 1  # 图片名称

obj=re.compile(r'<li class="i_list list_n2"> <a href="(?P<ur>.*?)" title=')
result=obj.finditer(resp.text)

obj3=re.compile(r'<!-- 正文图片显示 -->(?P<aa>.*?)<div',re.S)
obj4=re.compile(r'src="(?P<qq>.*?)">')

for item in result:
    # print(item.group("ur"))
    main_page = BeautifulSoup(resp.text, "html.parser")

    child_url = url+item.group("ur")
    child_resp = requests.get(child_url)  # 请求到子页面
    child_resp.encoding = "utf-8"

    r = obj3.search(child_resp.text)
    p=r.group("aa")
    w=obj4.search(p)
    y=w.group("qq")

    img_resp = requests.get(y)
    # print(img_resp.text)  # 注意, 图片不是文本. 不能获取text的内容
    with open(f"性感美女图片{n}.jpg", mode="wb") as f:  # 注意, 此时写入到文件的是字节. 所以必须是wb
        f.write(img_resp.content)  # 把图片信息写入到文件中

    print(f"{n}图片下载完毕")
    n += 1
    if n==6:
        break
print("美女图片下载完毕")
#   老师演示的时候,是去年的课程,还有点绿色。我现在打开,贼黄。忍不住下载了几张~哈哈
//***  补充
import requests
from bs4 import BeautifulSoup
import re

k=' <p><a href="/tupian/68362_2.html" title="下一页><img  src="https://oss-img.ojbkcdn.com/tutuji/20231018/xcp5ycmweti.jpg"></a></p>'

child_bs = BeautifulSoup(k, "html.parser")
div = child_bs.find("p")
di=div.find("a")
d=di.find("img").get("src")
print(d)   # https://oss-img.ojbkcdn.com/tutuji/20231018/xcp5ycmweti.jpg

//****************   图片  老师代码
import requests
from bs4 import BeautifulSoup

domain = "https://www.umei.net"
"""
注意, 
    子页面的url如果开头是/, 直接在前面拼接上域名即可
    子页面的url不是/开头, 此时需要找到主页面的url, 去掉最后一个/后面的所有内容. 和当前获取到的url进行拼接
"""
url = "https://www.umei.net/bizhitupian/xiaoqingxinbizhi/"
resp = requests.get(url)
resp.encoding = "utf-8"

n = 1  # 图片名称

main_page = BeautifulSoup(resp.text, "html.parser")
a_list = main_page.find_all("a", attrs={"class": "TypeBigPics"})
for a in a_list:
    href = a.get("href")
    child_url = domain + href
    child_resp = requests.get(child_url)  # 请求到子页面
    child_resp.encoding = "utf-8"
    # 子页面的bs对象
    child_bs = BeautifulSoup(child_resp.text, "html.parser")
    div = child_bs.find("div", attrs={"class": "ImageBody"})
    img_src = div.find("img").get("src")  # 拿到图片的下载路径
    # print(img_src)
    # 下载图片
    img_resp = requests.get(img_src)
    # print(img_resp.text)  # 注意, 图片不是文本. 不能获取text的内容
    with open(f"图片{n}.jpg", mode="wb") as f:  # 注意, 此时写入到文件的是字节. 所以必须是wb
        f.write(img_resp.content)  # 把图片信息写入到文件中

    print(f"{n}图片下载完毕")
    n += 1
//*********  xpath 入门
from lxml import etree

# 如果pycharm报错. 可以考虑这种导入方式
# from lxml import html
# etree = html.etree

xml = """
<book>
    <id>1</id>
    <name>野花遍地香</name>
    <name>hahaha </name>
    <price>1.23</price>
    <nick>臭豆腐</nick>
    <author>
        <nick id="10086">周大强</nick>
        <nick id="10010">周芷若</nick>
        <nick class="jay">周杰伦</nick>
        <nick class="jolin">蔡依林</nick>
        <div>
            <nick>惹了</nick>
        </div>
    </author>
    <partner>
        <nick id="ppc">胖胖陈</nick>
        <nick id="ppbc">胖胖不陈</nick>
    </partner>
</book>
"""
# 此时练习只能用XMLxml
et = etree.XML(xml)
result = et.xpath("/book")  # / 表示根节点
result = et.xpath("/book/name")   # 在xpath中间的/表示的是儿子
result = et.xpath("/book/name/text()")[0]   # text() 拿文本
result = et.xpath("/book//nick")  # //表示的是子孙后代.
result = et.xpath("/book/*/nick/text()")  # * 通配符. 谁都行
result = et.xpath("/book/author/nick[@class='jay']/text()")  # []表示属性筛选. @属性名=值   find(Nick, attrs={"class":"jay"})
result = et.xpath("/book/partner/nick/@id")  # 最后一个/表示拿到nick里面的id的内容, @属性. 可以直接拿到属性值
print(result)


# xpath处理HTML

html = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Title</title>
</head>
<body>
    <ul>
        <li><a href="http://www.baidu.com">百度</a></li>
        <li><a href="http://www.google.com">谷歌</a></li>
        <li><a href="http://www.sogou.com">搜狗</a></li>
    </ul>
    <ol>
        <li><a href="feiji">飞机</a></li>
        <li><a href="dapao">大炮</a></li>
        	<li><a href="huoche">火车</a></li>
    </ol>
    <div class="job">李嘉诚</div>
    <div class="common">胡辣汤</div>
</body>
</html>

"""

et = etree.HTML(html)
li_list = et.xpath("/html/body/ul/li[2]/a/text()")
print(li_list)


li_list = et.xpath("//li")
for li in li_list:
    href = li.xpath("./a/@href")[0]  # ./表示当前节点
    text = li.xpath("./a/text()")[0]  # ./表示当前节点
    print(text, href)
    # 后续的爬虫工作.....

//*******************   自己写的  没问题   58
"""
1. 拿到页面源代码
2. 从页面源代码中提取你需要的数据. 价格, 名称, 公司名称

"""
import re

import requests
from lxml import etree
headers={
	"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
url = "https://cq.58.com/ershouche/?utm_source=market&spm=u-2d2yxv86y3v43nkddh1.BDPCPZ_BT&PGTID=0d100000-0002-51f0-df9c-b9edf18814ef&ClickID=5"
resp = requests.get(url)
resp.encoding = "utf-8"
# print(resp.text)

# 提取数据
et = etree.HTML(resp.text)
print(5)
q=et.xpath("//ul[@class='infos infos-card h-clearfix']/li")
obj1=re.compile(r" (?P<ee>.*?)\n")
for item in q:
	wan=item.xpath("./div/a/div/span/text()")
	date=item.xpath("./div/a/p/text()")
	if not date:  # 过滤掉无用的数据
		continue
	if not wan:  # 过滤掉无用的数据
		continue
	t=item.xpath("./div/a/div[2]/h2/span/font/text()")
	w=item.xpath("./div/a/div[2]/h2/span/text()")
	o=item.xpath("./div/a/div[2]/div[2]/text()")
	p=obj1.search(w[0])
	u=p.group("ee")
	# print(date[0],t[0],u)
	# print(u)
	print(t,o,w,u,date,wan)

//**********   老师演示

"""
1. 拿到页面源代码
2. 从页面源代码中提取你需要的数据. 价格, 名称, 公司名称

"""
import requests
from lxml import etree

url = "https://beijing.zbj.com/search/f/?type=new&kw=saas"
resp = requests.get(url)
resp.encoding = "utf-8"
# print(resp.text)

# 提取数据
et = etree.HTML(resp.text)
divs = et.xpath("//div[@class='new-service-wrap']/div")
for div in divs:
    # 此时的div就是一条数据. 对应一个商品信息
    # 商品价格
    price = div.xpath("./div/div/a/div[2]/div[1]/span[1]/text()")
    if not price:  # 过滤掉无用的数据
        continue
    price = price[0]
    company = div.xpath("./div/div/a[2]/div[1]/p/text()")[0]
    # name = div.xpath("./div/div/a[1]/div[2]/div[2]/p//text()")  # //表示提取p的所有文本, 包括子子孙孙所有内容
    # name = "".join(name)
    print(company)



# r = "_".join(["张无忌", "麻花藤", "码云"])
# print(r)

//**********************    Pyquery
from pyquery import PyQuery

html = """
    <ul>
       <li class="aaa"><a href="http://www.google.com">谷歌</a></li>
       <li class="aaa"><a href="http://www.baidu.com">百度</a></li>
       <li class="bbb" id="qq"><a href="http://www.qq.com">腾讯</a></li>
       <li class="bbb"><a href="http://www.yuanlai.com">猿来</a></li>
   </ul>
"""

# 加载html内容
p = PyQuery(html)

print(p)
print(type(p))
# pyquery对象直接(css选择器)

a = p("a")
print(a)
print(type(a))  # 依然是pyquery对象

# 链式操作
a = p("li")("a")
print(a)

a = p("li a")
print(a)

a = p(".aaa a")  # class="aaa"   aaa类的a标签
print(a)

a = p("#qq a")  # id="qq"
print(a)

href = p("#qq a").attr("href")  # 拿属性
text = p("#qq a").text()  # 拿文本
print(text)

# 坑, 如果多个标签同时拿属性. 只能默认拿到第一个
href = p("li a").attr("href")
print(href)

# 多个标签拿属性
it = p("li a").items()
for item in it:  # 从迭代器中拿到每一个标签
    href = item.attr("href")  # 拿到href属性
    text = item.text()
    print(text, href)


# 快速总结:
# 1. pyquery(选择器)
# 2. items()  当选择器选择的内容很多的时候. 需要一个一个处理的时候
# 3. attr(属性名)  获取属性信息
# 4. text() 获取文本


div = """
    <div><span>我爱你</span></div>
"""
p = PyQuery(div)
html = p("div").html()  # 全都要
text = p("div").text()  # 只要文本, 所有的HTML标签被过滤掉
print(html)   # <span>我爱你</span>
print(text)    # 我爱你

html = """
<HTML>
    <div class="aaa">哒哒哒</div>
    <div class="bbb">嘟嘟嘟</div>
</HTML>
"""

p = PyQuery(html)

# 在xxxx标签后面添加xxxxx新标签
p("div.aaa").after("""<div class="ccc">吼吼吼</div>""")
p("div.aaa").append("""<span>我爱你</span>""")

p("div.bbb").attr("class", "aaa")  # 修改属性
p("div.bbb").attr("id", "12306")  # 新增属性, 前提是该标签没有这个属性
p("div.bbb").remove_attr("id")  # 删除属性
p("div.bbb").remove()  # 删除标签
print(p)

dic = {}
dic['jay'] = "周杰伦"
print(dic)
dic['jay'] = "呵呵哒"
print(dic)


//****************  pyquery实战案例       
				# pyquery 处理页面结构不规整的个情况   强行塞入确实部分,使结构完整
"""
1, 提取页面源代码
2, 解析页面源代码. 提取数据
"""
import requests
from pyquery import PyQuery


def get_page_source(url):
    resp = requests.get(url)
    resp.encoding = "gbk"
    return resp.text


def parse_page_source(html):
    doc = PyQuery(html)
    mt_list = doc(".mt-10").items()  # class="mt-10"
    for mt in mt_list:  # 拿到每一个mt

        # 判断是否有汽车经销商
        if not mt("div > dl:nth-child(3) > dt:contains(购车经销商)"):
            # 向 地点 后添加购车经销商进去
            mt("div > dl:nth-child(2)").after(PyQuery("""<dl class="choose-dl">
                        <dt>购车经销商</dt>
                        <dd>
                            <a href="###" class="js-dearname" data-val='125965,47759' data-evalid="3629818" target="_blank">
                                &nbsp
                            </a>
                        </dd>
                    </dl>"""))

        # 提取购买的车型
        # 想要在已经提取的内容中获取第一个怎么办?  eq(0)
        # nth-child(1) 在css进行选择的时候.选取第1个位置的内容
        chexing = mt("div > dl:nth-child(1) > dd").eq(0).text().replace("\n", "").replace(" ", "")
        didian = mt("div > dl:nth-child(2) > dd").text()
        shijian = mt("div > dl:nth-child(4) > dd").text()
        jiage = mt("div > dl:nth-child(5) > dd").text().replace(" 万元", "")
        youhao = mt("div > dl:nth-child(6) > dd > p:nth-child(1)").text().replace(" 升/百公里", "")
        gonglishu = mt("div > dl:nth-child(6) > dd > p:nth-child(2)").text().replace(" 公里", "")
        other = mt("div > div > dl > dd").text().split()
        print(other)
        # 存储到文件中.......


def main():
    url = "https://k.autohome.com.cn/146/"
    # 1, 提取页面源代码
    html = get_page_source(url)
    # 2, 解析页面源代码.提取数据
    parse_page_source(html)


if __name__ == '__main__':
    main()


//**********  结束  数据解析部分







  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值