from urllib.request import urlopen
url = "http://www.baidu.com"
ret = urlopen(url)
print(ret) # <http.client.HTTPResponse object at 0x00000231707000A0>
print(ret.read()) # b'...' 是个字节,需要解码,需要字符集
print(ret.read().decode("utf-8"))
with open("mybaidu.html", mode="w", encoding="utf-8") as f:
f.write(ret.read().decode("utf-8"))
# 安装模块request
pip install requests
# 文件名不要跟模块名重名
import requests
url="http://www.baidu.com"
ret = requests.get(url)
print(ret) # <Response [200]>
ret.encoding="utf-8"
print(ret.text)
# 添加一个请求头信息
# sogou搜索,需要请求头
import requests
content="周杰伦"
url = f"https://www.sogou.com/web?query={content}"
headers={
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36"
}
ret = requests.get(url,headers=headers)
print(ret.text)
# print(ret.request.headers) 打印请求头
# 百度翻译,自动加载的翻译内容 post请求
# form data : kw:dog
import requests
url = "https://fanyi.baidu.com/sug"
# data = {"kw":"dog"}
# data = {"kw":input("请输入一个单词")}
ret = requests.post(url,data=data)
print(ret.text)
# 输出的json,可以引入json模块 import json 或者 直接.json()
print(ret.json()) # .json()返回的是一个字典,.text返回的是一个字符串
# 字典可以直接拿数据
print(ret.json()["data"][0]["v"]) # dog n. 狗; 蹩脚货; 丑女人; 卑鄙小人 v. 困扰; 跟踪
# 豆瓣排行榜
import requests
url="https://movie.douban.com/j/chart/top_lis"
data={
"type": "11",
"interval_id": "100:90",
"action": "",
"start": "0",
"limit": "20"
}
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36"
}
ret = requests.get(url,params=data,headers=headers) # 处理一个反爬
print(ret.text)
print(ret.request.url)
# https://movie.douban.com/j/chart/top_list?
# type=11&interval_id=100%3A90&action=&start=0&limit=20
# 输出的也是json数据
print(ret.json())
# 数据解析,四种方式可以混合使用
# 1.re正则解析 2.bs4解析,简洁明了,效率不高
# 3.xpath解析,新颖,简洁干练 4.pyquery解析,模仿前端的jquery选择器解析
# 正则表达式
# 速度快,效率高,有难度
# . 匹配 除换行符之外的任意字符,re模块中是个坑,不能匹配换行符
# \w 匹配字母或数字或下划线
# \s 匹配任意的空白符
# \d 匹配任意数字
# \n 匹配一个换行符
# \t 匹配一个制表符
# ^ 匹配字符串的开始
# $ 匹配字符串的结尾
# 大写 表示 非
# \W 匹配 非 字母或数字或下划线
# \D 匹配非数字
# \S 匹配非空白符
# | 或
# () 表示一个组
# [] 匹配字符串组中的字符,方括号中有就匹配
# [a-zA-Z0-9] 把大小写字母和数字都匹配出来
# [^xxx] 表示非,除了后面的都匹配出来
# [^a-zA-z0-9] 把除了大小写字母和数字之外的都匹配出来,比如汉字、符号
# 量词 : 控制前面的元字符出现的次数
# * 重复0次或多次 ≥0 {0,}
# + 重复1次或多次 ≥1 {1,}
# ? 重复0次或1次 0 or 1
# {n} 重复n次 n
# {n,} 重复n次或多次 ≥n
# {n,m} 重复n到m次 n< <m
# 贪婪匹配 和 惰性匹配
# .* 贪婪匹配
# .*? 惰性匹配
# .* 尽可能多的匹配
# 玩儿.*游戏 => 匹配尽可能多的,从第一个玩儿,到最后一个游戏之间都匹配
# 玩儿.*?游戏 => 匹配尽可能少的,从第一个玩儿,到最近的一个游戏之间的匹配
# .* 一直找到最后一个游戏
# .*? 直接找第一个游戏 ==> 回溯
# 题目 <div class="abc"><div>胡辣汤</div><div>饭团</div></div>
<div>.*?</div> # 最小匹配div,
# <div>胡辣汤</div>
# <div>饭团</div>
# 123x456x789x
.*?x
# => 123x 456x 789x 三个匹配结果
# .*? 惰性匹配用的多
# re模块,是python内置模块
ret = re.findall("a","abca")
print(ret) # => ['a','a']
# 格式化是 f"",转义\d前面加r,防止转义
# findall
# findall 直接返回列表
ret = re.findall(r"\d+","abc332cde56")
print(ret) # => ['332','56']
# finditer
ret = re.finditer(r"\d+","123aa33bb")
# finditer找出来的是迭代器
for item in ret:
print(item) # <re.Match object; span=(0,3),match='123'>
# <re.Match object; span(5,7),match='33'>
print(item.group()) # 123 33
# search
ret = re.search(r"\d+","abc33,ccd68b")
print(ret) # <re.Match object; span=(3, 5), match='33'>
# re.search只拿到匹配到的第一个
print(ret.group()) # 33
# match
# match 从字符串的开头开始匹配,^
re.match(r"\d+","bad33")
# 相当于 r"^\d+"
# 预加载
# 预加载,就是把正则对象提前加载完成
obj = re.compile(r"\d+")
for item in items:
obj.finditer(item)
ret = obj.findall("我叫周杰伦,今年32岁,就读3年2班"
print(ret) # => ['32', '3', '2']
# coding:gbk
import re
f = open("D://全国各地行政区划代码及身份证号前6位查询.html", mode="r", encoding="gbk")
content = f.read()
obj = re.compile(r"target=_blank>.*?<a href=")
ob1 = re.compile(r".*?([\u4E00-\u9FA5]+).*?")
ob2 = re.compile(r"\d+")
ret = obj.findall(content)
for item in ret:
d1 = ob1.findall(item)
d2 = ob2.findall(item)
print(d1[0],d2[0])
import re
s = """
<div class='西游记'><span id='10010'>中国联通</span></div>
<div class='三国志'><span id='10086'>中国移动</span></div>
"""
obj = re.compile(r"<span id='(\d+)'>(.*?)</span>")
ret = obj.findall(s)
print(ret) # [('10010', '中国联通'), ('10086', '中国移动')]
# 正则 加上小括号,就直接得出小括号里面的内容
obj = re.compile(r"<span id='(?P<id>\d+)'>(?P<name>.*?)</span>")
ret = obj.finditer(s)
for item in ret:
id=item.group("id")
name=item.group("name")
print(id,name)
# 小括号里加上 ?P<id> 值就赋值给id了。 (?P<名字>正则)
# coding:gbk
import re
import requests
# 豆瓣top250
# request.get().text
# csv 文件是数据与数据之间使用逗号隔开
f = open("top250.csv",mode="w", encoding="gbk")
# python 有csv模块 但有自己换行
url = "https://movie.douban.com/top250"
# url = "https://movie.douban.com/top250?start=25&filter="
num = 0
params = {
"start":num*25,
"filter":""
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36"
}
index = 0
for i in range(10):
num = i
ret = requests.get(url,params=params,headers=headers)
ret.encoding='utf-8' # 解决中文乱码问题
source = ret.text
# 编写正则,获取需要的top250数据
obj = re.compile(r'<li>.*?<span class="title">(?P<title>.*?)</span>.*?</li>',re.S)
# 重要 -----------
# re.S 可以让. 匹配换行符,特别是在源代码中,有换行
# 重要 -----------
titles = obj.finditer(source)
for item in titles:
index +=1
title = item.group("title").strip() # 去掉前后的空白 有的话才加strip
f.write(f"序号:{index},电影名称:{title}\n") # \n 换行
f.close()
ret.close()
print("已经完成了!")
# 如何翻页 (页数-1)*25