cookie 是网站用来辨别用户身份,进行会话跟踪,存储在本地终端上的数据
session(会话)本来含义是指有始有终的一系列动作和消息,在 web
中,session 主要用来在服务器端存储特定用户对象会话所需要的信息
cookie 由服务器产生,浏览器第一次请求,服务器发送给客户端进而保存,浏览器继续
访问时,就会在请求头的 cookie 字段上附带 cookie 信息,这样服务器就可以识别是谁在访问了,但是 cookie 存在缺陷:
不安全—本地保存,容易被篡改
大小受限,本身最大 4kb
cookie 虽然在一定程度上解决了‘保持状态’的需求,但是我们希望有一种新的技术可以
克服 cookie 缺陷,这种技术就是 session
session 在服务器保存—解决安全问题
那么,问题来了:服务器上有 session,但是客户端的请求发送过来,服务器如何知道
session_a,session_b,到底和哪个请求对应。所以,为了解决这个问题:cookie 就作为这个桥
梁。在 cookie 有一个 sessionid 字段,可以用来表示这个请求对应服务器中的哪一个 session
禁用 cookie,一般情况下,session 也无法使用。特殊情况下可以使用 url 重写技术来使
用 session url 重写技术:将 sessionid 拼接到 url 里面
session 的生命周期:服务器创建开始,有效期结束(一般网站设定都是大约 30 分钟左右)就删除
案列:
第一种实现方法:将浏览器中的 cookie 信息封装到请求头中
第二种实现方法:使用 session 对象
在 requests 里,session 对象是一个非常常用的对象,这个对象代表一次用户会话:从客 户端浏览器连接服务器开始,到客户端浏览器与服务器断开
会话能让我们在跨请求时候保持某些参数,比如在同一个 session 实例发出的所有请求之间保持 cookie
import requests
def login1():
'''
使用cookie的方式登录。
cookie中保存登录的信息。
只需要将登录后的cookie放到headers请求头中,即可做到登录。
:return:
'''
# 准备参数
ueser_url = 'http://www.kaixin001.com/home/?uid=181913414&s=97'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
'Cookie': '_ref=5f03d27a82be5; _cpmuid=1245916791; SERVERID=_srv80-83_; Hm_lvt_500f908d39095efce74d0e9c64f55ffb=1594086009; _vid=C8F8FA1093F0000176B486C0E2AD9200; _user=0eeb7e8d9ef344afcca8659fc5fee07f_181913414_1594086028; _preemail=13016031459; _uid=181913414; _email=13016031459; _laid=0; _sso=181913414; Hm_lpvt_500f908d39095efce74d0e9c64f55ffb=1594086030; noFocusContent=1; onlinenum=c%3A0; wpresence=OQhrc-f0Ev8LTeGNeLhtSSApTOle4edVXwPSlA.ZGZ0MTgxOTEzNDE0',
}
# 发送请求,获取响应
response = requests.get(ueser_url, headers=headers)
print(response.text)
def login2():
'''
使用用户名和密码进行登录
:return:
'''
# 登录将用户名和密码提交的url
login_url = 'https://security.kaixin001.com/login/login_post.php'
# 个人首页url
user_url = 'http://www.kaixin001.com/home/?uid=181913414&s=9'
# requests模块session对象
# 登录步骤:
# 1、创建session对象
se = requests.Session()
# 2、使用session对象进行登录,此时session对象就会记录登录状态
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
}
data = {
'loginemail': '13016031459',
'password': 'Abc1234%',
}
se.post(login_url, headers=headers, data=data)
# 3、使用登录后的session请求个人首页
response = se.get(user_url, headers=headers)
# print(response.text)
if '王富东' in response.text:
print('登录成功!')
if __name__ == '__main__':
login2()
代理实际上指的就是代理服务器,英文叫作 proxy server,它的功能是代理网络用户去 取得网络信息。形象地说,它是网络信息的中转站。在我们正常请求一个网站时,是发送了 请求给 web 服务器,web 服务器把响应传回给我们。如果设置了代理服务器,实际上就是 在本机和服务器之间搭建了一个桥,此时本机不是直接向 web 服务器发起请求,而是向代 理服务器发出请求,请求会发送给代理服务器,然后由代理服务器再发送给 web 服务器, 接着由代理服务器再把 web 服务器返回的响应转发给本机。这样我们同样可以正常访问网 页,但这个过程中 web 服务器识别出的真实 IP 就不再是我们本机的 IP 了,就成功实现了 IP 伪装,这就是代理的基本原理
import requests
# https://www.kuaidaili.com/free
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
}
# 代理字典
proxies = {
'http': 'http://125.108.121.28:9000'
}
response = requests.get('https://www.baidu.com/', headers=headers, proxies=proxies)
# 设置代理之后,请求超时,换一个代理。
# 买
# 做一个代理池
print(response.status_code)
(1)、数据的结构化分类
一般来讲对我们而言,需要抓取的是某个网站或者某个应用的内容,提取有用的价值,内容一般分为三部分,结构化的数据、半结构化的数据和非结构化数据
1.结构化数据:
定义:可以用统一的结构表示的数据,可以使用关系型数据库表示和存储,表现为二维形式的数据
特点:数据以行为单位,一行数据表示一个实体的信息,每一行的数据的属性是相同的
处理方法:sql语句
2、半结构化数据:
定义:使用相关标记进行数据存储和分类的数据结构
特点:自描述的结构,常见的半结构数据有:html,xml 和 json 等
处理方法:xpath,正则表达式
3、非结构化数据:
定义:就是没有固定的结构。各种文档,图片,视频或者音频等等…
特点:非结构化数据
处理方式:对于这类数据,我们一般直接整体进行存储,而且一般存储为二进制形式
Json(JavaScript Object Notation,JS 对象标记)是一种轻量级的数据交换格式,json 是 js 对象的字符串表达式,他使用文本形式表示一个 js 对象的信息,本质是一个字符串
Js 中对象和数组是比较特殊并且常用的两种类型:
1.对象表示为键值对
2.数据有逗号分隔
3.大括号保存对象
4.方括号保存数组
如下为一组 json 字符串:
{
"status":"1",
"data":{
"cityData":{
"cities":{
},
"hotCitys":[
{
"adcode":"100000",
"name":"全国",
"label":"全国",
"spell":"",
"x":"116.3683244",
"y":"39.915085",
"citycode":"total"
},
"version":"202062921"
},
"update":true
}
json 模块有两个方法 dumps 和 loads 方法,其参数和返回值如下:
(1)将 python 类型转为 json 字符串类型:
json 字符串= json.dumps(python 类型)
(2)将 json 字符串类型转为 Python 类型(python 的 list 或者字典:
Python 的 list 或者字典 = json.loads(json 的字符串格式)
import requests
def get_json(url):
'''
请求url,获取响应内容
:param url:
:return:响应内容
'''
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
}
response = requests.get(url, headers=headers)
return response.json()
def get_city_adcodes():
'''
先获取城市的adcode
:return: [(name,adcode)]
'''
city_infos = []
base_url = 'https://www.amap.com/service/cityList?version='
json_data = get_json(base_url)
# print(json_data)
for i, data in enumerate(json_data['data']['cityData']['hotCitys']):
if i > 0:
city_infos.append((data['name'], data['adcode']))
return city_infos
def get_weather_info(name, adcode):
'''
通过adcode去获取城市的天气信息。
:param name: 城市的名称
:param adcode: 城市adcode
:return:
'''
base_url = 'https://www.amap.com/service/weather?adcode={}'.format(adcode)
json_data = get_json(base_url)
# print(name,json_data)
weather_name = json_data['data']['data'][0]['live']['weather_name']
max_temp = json_data['data']['data'][0]['forecast_data'][0]['max_temp']
min_temp = json_data['data']['data'][0]['forecast_data'][0]['min_temp']
item = {
}
item['城市'] = name
item['温度'] = f'{min_temp}/{max_temp}°C'
item['天气'] = weather_name
print(item)
pass
def main():
# 1、先获取城市的adcode
adcode_list = get_city_adcodes()
# print(adcode_list)
# 2、通过adcode去获取城市的天气信息。
for name, adcode in adcode_list:
get_weather_info(name, adcode)
if __name__ == '__main__':
main()
正则表达式,又称规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本
元字符 | 含义 |
---|---|
^ | 匹配行首 |
$ | 匹配行尾 |
? | 重复匹配 0 次或 1 次 |
* | 重复匹配 0 次或更多次 |
+ | 重复匹配 1 次或更多次 》1 |
{n,} | 重复 n 次或更多次 |
{n,m} | 重复 n~m 次 |
{n} | 重复 n 次 |
[a-z] | 任意 a-z 的字母 |
[abc] | a/b/c 中的任意一个字符 |
[^123abc] | 匹配除了 123 abc 这几个字符以外的任意字符 |
. | 匹配除换行符以外的任意一个字符 |
\b | 匹配单词的开始和结束 |
\B | 匹配不是单词开始和结束的位置 |
\d | 匹配数字 |
\D | 匹配任意非数字的字符 |
\w | 匹配字母,数字,下划线 |
\W | 匹配任意不是字母,数字,下划线的字符 |
\s | 匹配任意空白,包括空格,制表符(Tab),换行符 |
\S | 匹配任意不是空白符的字符 |
[^a] | 匹配除了 a 以外的任意字符 |
123|abc | 匹配 123 或者 abc |
在 Python 中,我们可以使用内置的 re 模块来使用正则表达式。有一点需要特别注意 的是,正则表达式使用对特殊字符进行转义,所以如果我们要使用原始字符串,只需加一个 r 前缀
第一步:使用 compile()函数将正则表达式的字符串形式编译为一个 Pattern 对象
第二步:通过 Pattern 对象提供的一系列方法对文本进行匹配查找,获得匹配结果,一 个 Match 对象
第三部:最后使用 Match 对象提供的属性和方法获得信息,根据需要进行其他的操作
compile 函数用于编译正则表达式,生成一个 Pattern 对象,它的一般使用形式如下:
在上面,我们已将一个正则表达式编译成 Pattern 对象,接下来,我们就可以利用 pattern 的 一系列方法对文本进行匹配查找了
Pattern 对象的一些常用方法主要有:
方法 | 描述 |
---|---|
match | 从起始位置开始查找,一次匹配 |
search | 从任何位置开始查找,一次匹配 |
findall | 全部匹配,返回列表 |
finditer | 全部匹配,返回迭代器 |
split | 分割字符串,返回列表 |
sub | 替换 |
match 方法用于查找字符串的头部(也可以指定起始位置),它是一次匹配,只要找到了 一个匹配的结果就返回,而不是查找所有匹配的结果,它的一般使用形式如下:
Match = pattern.match(
string,# 要匹配的目标字符串
start,# 要匹配目标字符串的起始位置(可选)
end # 结束位置(可选)
)
import re
pattern = re.compile(r'\d+')
content = 'one12twothree34four'
m1 = pattern.match(content) # 从0开始匹配
m2 = pattern.match(content, 2, 10) # 从e位置开始匹配
m3 = pattern.match(content, 3, 10) # 从1位置开始匹配
print(m1) # None
print(m2) # None
print(m3.group()) # 12
print(m3.group(0)) # 12 可以省略
print(m3.start(0)) # 3 起始位置
print(m3.end(0)) # 5 结束位置
print(m3.span()) # (3,5)起始位置,结束位置
其中,string 是待匹配的字符串,pos 和 endpos 是可选参数,指定字符串的起始和终点 位置,默认值分别是 0 和 len (字符串长度)
因此,当你不指定 pos 和 endpos 时,match 方法默认匹配字符串的头部
当匹配成功时,返回一个 Match 对象,如果没有匹配上,则返回 None
在上面,当匹配成功时返回一个 Match 对象,其中:
group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配
的子串时,可直接使用 group()或 group(0);start([group])方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
end([group])方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
span([group])方法返回(start(group),end(group))
search 方法用于查找字符串的任何位置,它也是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果,它的一般使用形式如下:
其中,string 是待匹配的字符串,pos 和 endpos 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)
当匹配成功时,返回一个 Match 对象,如果没有匹配上,则返回 None
Match = pattern.search(
string,#要匹配的目标字符串
start,#要匹配目标字符串的起始位置(可选)
end#结束位置(可选)
)
import re
pattern = re.compile(r'\d+')
content = 'one12twothree34four'
m = pattern.search(content)
print(m) #
print(m.group()) # 12
m = pattern.search(content, 10, 30)
print(m) #
print(m.group()) # 34
print(m.span()) # (13, 15)
其中,string 是待匹配的字符串,pos 和 endpos 是可选参数,指定字符串的起始和终点
位置,默认值分别是 0 和 len (字符串长度)。findall 以列表形式返回全部能匹配的子串,如 果没有匹配,则返回一个空列表。
回到前面的小例子,使用普通字符匹配:
list= pattern.findall(
string,#要匹配的目标字符串
start,#要匹配目标字符串的起始位置(可选)
end#结束位置(可选)
)
import re
# 生成pattern对象,查找连续的数字
pattern = re.compile(r'\d+')
result1 = pattern.findall('hello 123456 789')
# 从0开始 1对应的是下标3 2对应的是下标7 匹配下标为0-7的数字,要前不要后
result2 = pattern.findall('one1two2three3four4', 0, 8)
print(result1, result2) # ['123456', '789'] ['12']
finditer 方法的行为跟 findall 的行为类似,也是搜索整个字符串,获得所有匹配的结果
但它返回一个顺序访问每一个匹配结果(Match 对象)的迭代器
import re
pattern = re.compile(r'\d+')
content1 = 'hello 123456 789'
content2 = 'one1two2three3four4'
result_iter1 = pattern.finditer(content1)
result_iter2 = pattern.finditer(content2, 0, 10)
print(type(result_iter1)) # 迭代器
print(type(result_iter2)) # 迭代器
print('result1....')
for m1 in result_iter1:
print('matching string:{},positions:{}'.format(m1.group(),
m1.span())) # matching string:123456,positions:(6, 12), matching string:789,positions:(13, 16)
print('result2.....')
for m2 in result_iter2:
print('matching string:{},position:{}'.format(m2.group(),
m2.span())) # matching string:1,position:(3, 4),matching string:2,position:(7, 8)
split 方法按照能够匹配的子串将字符串分割后返回列表
Pattern.split(
String,
Maxsplit # 指定最大分隔次数,默认全部分隔,可选
)
import re
p = re.compile(r'[\s\,\;]+')
a = p.split('a b c d')
print(a) # ['a', 'b', 'c', 'd']
其中,maxsplit 用于指定最大分割次数,不指定将全部分割
sub 方法用于替换,它的使用形式如下:
Pattern.sub(
repl, #替换成什么
String,#替换什么
Count#替换次数
)
import re
p = re.compile(r'(\w+) (\w+)')
s = 'hello 123,hello 456'
# hello world,hello world
print(p.sub(r'hello world', s)) # 使用'hello world'替换 'hello 123,hello 456'
# 123 hello,456 hello
print(p.sub(r'\2 \1', s)) # 引用分组
def func(m):
print(m.group(2)) # 123, 456
return 'hi' + ' ' + m.group(2)
print(p.sub(func, s)) # hi 123,hi 456
print(p.sub(func, s, 1)) # 123 hi 123,hello 456
其中,repl 可以是字符串也可以是一个函数:
如果 repl 是字符串,则会使用 repl 去替换字符串每一个匹配的子串,并返回替换后的 字符串,另外,repl 还可以使用 id 的形式来引用分组,但不能使用编号 0
如果 repl 是函数,这个方法应当只接受一个参数(Match 对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)
count 用于指定最多替换次数,不指定时全部替换
在某些情况下,我们想匹配文本中的汉字,有一点需要注意的是,中文的 unicode 编码
范围主要在[u4e00-u9fa5],这里说主要是因为这个范围并不完整,比如没有包括全角(中文)标点,不过,在大部分情况下,应该是够用的
假设现在想把字符串 title = ‘你好,hello,世界’ 中的中文提取出来,可以这么做:
import re
title = '您好,hellp,世界'
pattern = re.compile('[\u4e00-\u9fa5]+')
result = pattern.findall(title)
print(result) # ['您好', '世界']
正则表达式中,“.”的作用是匹配除“\n”以外的任何字符,也就是说,它是在一行中进行 匹配。这里的“行”是以“\n”进行区分的。a 字符串有每行的末尾有一个“\n”,不过它不可见
如果不使用 re.S 参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始, 不会跨行。而使用 re.S 参数以后,正则表达式会将这个字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,在整体中进行匹配
贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配( * );
非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配( ? );
Python 里数量词默认是贪婪的
分组在正则表达式中就是用()来表示的。一个括号就是一个分组。分组的作用主要有 以下两个:
(1)、筛选特点内容
通过给特点的内容加一个(),将来可以通过 group(1)方式取到这个括号内的东西。
(2)、反向引用:可以在同一个表达式中引用前面的分组表达式
import re
import requests
def get_content(url):
'''
请求url,获取响应内容
:param url:
:return: 页面的字符串内容
'''
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'
}
response = requests.get(url, headers=headers)
return response.text
def parse_page(html_str):
'''
使用正则提取页面信息
:param html_str:
:return:
'''
# 正则提取页面信息的核心思想:一步一步取缩小提取范围,最后做到精确查找。
dl_p = re.compile(r'(.*?)
', re.S)
dl_c = dl_p.search(html_str).group(1)
# print(dl_c)
# 获取每一个dd
dd_p = re.compile(r'(.*?) ', re.S)
dd_c_list = dd_p.findall(dl_c)
# print(dd_c_list)
# 遍历包含每个电影list,解析获取每条电影
for dd in dd_c_list:
movie_name = re.search(r'title="(.*?)" class=', dd, re.S).group(1)
# print(movie_name)
actors = re.search(r'(.*?)
', dd, re.S).group(1).strip()
# print(actors)
play_date = re.search(r'上映时间:(.*?)
', dd, re.S).group(1)
# print(play_date)
# 评分
scores_p = re.compile(r'(.*?)(.*?)', re.S)
scores = scores_p.search(dd).group(1) + scores_p.search(dd).group(2)
# print(scores_p)
# 详情页链接
detail_p = re.compile(r' + detail_p.search(dd).group(1)
item = {
}
item['movie_name'] = movie_name
item['actors'] = actors
item['play_date'] = play_date
item['scores'] = scores
item['detail'] = detail
print(item)
def main():
# 1确定url
base_url = 'https://maoyan.com/board/4?offset=%s'
# 2实现分页
for i in range(10):
# 3、发送请求,获取页面内容
html_str = get_content(base_url % (i * 10))
# 测试
# print(html_str)
# 4、从页面中解析出电影信息。
parse_page(html_str)
if __name__ == '__main__':
main()
import requests,re,json
def get_json(url):
'''
请求url,获取响应json数据
:param url:
:return:json_data
'''
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
'cookie': 'cna=smyJFzWX9S8CAdxzrxpGOakl; cookie2=1a93d2fdbecc71e2cca488c954bc34d2; t=f8452a53fb1eec35c8806e886fb67ff8; _tb_token_=e3e1a8f7d7356; l=eBaefzngOOBB1VGABO5Courza77OWIRb4oVzaNbMiInca6wl_nTCQNQqNo2k8dtjgt1F9etr5vXjARLHR3AGdlSBKP9OynKxnxf..; isg=BEpKJsZEIYCW9a0rekh-NT16mzDsO86VhJk8M9SDCR1Oh-pBvM9Ppcz5l_Nbc0Yt',
'referer': 'https://www.taobao.com/markets/3c/tbdc?spm=a21bo.2017.201867-main.11.5af911d9WqhgGA?spm=a21bo.2017.201867-main.11.5af911d9WqhgGA',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
}
response = requests.get(url,headers = headers)
#使用正则提取出json字符串
json_str = re.search(r'{.*}',response.text).group()
print(json_str)
return json.loads(json_str)
def parse_data(json_data):
'''
提取数据
:param json_data:
:return:
'''
# print(json_data)
try:
result = json_data['result']
try:
for k, v in result.items():
try:
for data in v['result']:
item = {
}
item['item_title'] = data['item_title']
item['item_current_price'] = data['item_current_price']
item['item_pic'] = 'http:' + data['item_pic']
item['item_url'] = 'https:' + data['item_url']
print(item)
except KeyError:
pass
print('===========================')
except Exception:
for data in result:
item = {
}
item['item_title'] = data['item_title']
item['item_current_price'] = data['item_current_price']
item['item_pic'] = 'http:' + data['item_pic']
item['item_url'] = 'https:' + data['item_url']
print(item)
print('==========================')
except Exception:
pass
def main():
#1、确定url
url_list = [
#ttps://tce.taobao.com/api/mget.htm?callback=jsonp1389&tce_sid=1870299&tce_vid=1&tid=&tab=&topic=&count=&env=online
'https://drc.alicdn.com/7/1870299_1____?callback=jsonp1870299_1____',#
#https://tce.taobao.com/api/mget.htm?callback=jsonp1593&tce_sid=1870316,1871653&tce_vid=2,2&tid=,&tab=,&topic=,&count=,&env=online,online
'https://drc.alicdn.com/7/1870316_2____?callback=jsonp1870316_2____',#手机
#'https://tce.taobao.com/api/mget.htm?callback=jsonp1670&tce_sid=1870321,1871654&tce_vid=2,2&tid=,&tab=,&topic=,&count=,&env=online,online',#游戏设备
'https://drc.alicdn.com/7/1870321_2____?callback=jsonp1870321_2____',
'https://tce.taobao.com/api/mget.htm?callback=jsonp1844&tce_sid=1870340,1871656&tce_vid=2,2&tid=,&tab=,&topic=,&count=,&env=online,online',#相机摄影、
'https://tce.taobao.com/api/mget.htm?callback=jsonp1900&tce_sid=1870341,1871659&tce_vid=2,2&tid=,&tab=,&topic=,&count=,&env=online,online',#生活厨电
'https://tce.taobao.com/api/mget.htm?callback=jsonp2105&tce_sid=1870343,1871658&tce_vid=2,2&tid=,&tab=,&topic=,&count=,&env=online,online',#个人护理
]
#2.请求url,获取数据
for url in url_list:
json_data = get_json(url)
#从json数据中提取出商品信息
parse_data(json_data)
if __name__ == '__main__':
main()
import requests,re
# 请求
def request_html(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36',
}
response = requests.get(url=url,headers=headers).content.decode('utf-8')
return response
# 提取数据
def get_data(response,i):
# 提取热门信息ul标签
ul_pattern = re.compile(r'(.*?)
',re.S)
ul=ul_pattern.findall(response)[0]
# 提取li标签
li_pattern = re.compile(r'(.*?) ',re.S)
li_list = li_pattern.findall(ul)
for li in li_list:
readers_pattern = re.compile(r'(.*?)',re.S)
readers_list = readers_pattern.findall(li)
# 阅读
readers = readers_list[0].strip()
# 评论
comment = readers_list[1].strip()
print(readers,comment)
# 贴吧名称
tieba_name_pattern = re.compile(r'.*class="balink">(.*?)',re.S)
try:
tieba_name = tieba_name_pattern.findall(li)[0]
except:
tieba_name = 'None'
print(tieba_name)
# 标题
title_pattern = re.compile(r'title="(.*?)" class="note"',re.S)
title = title_pattern.findall(li)[0]
print(str(title))
# 作者
writer_pattern = re.compile(r'target="_blank">(.*?)',re.S)
writer = writer_pattern.findall(li)[0]
print(writer)
# 时间
time_pattern = re.compile(r'(.*?)',re.S)
time = time_pattern.findall(li)[0]
print(time)
infor = readers + ':' + comment + ':' + tieba_name + ':' + title + ':' + writer + ':' + time
print(infor)
with open(f'guba{i}.txt','a',encoding='utf8') as f:
f.write(infor+'\n')
if __name__ == '__main__':
for i in range(1,2):
url = f'http://guba.eastmoney.com/default,99_{i}.html'
response = request_html(url)
get_data(response,i)