爬虫模拟登录和代理及正则

爬虫模拟登录和代理设置

一、cookie和session

cookie 是网站用来辨别用户身份,进行会话跟踪,存储在本地终端上的数据

session(会话)本来含义是指有始有终的一系列动作和消息,在 web
中,session 主要用来在服务器端存储特定用户对象会话所需要的信息

cookie原理:

cookie 由服务器产生,浏览器第一次请求,服务器发送给客户端进而保存,浏览器继续

访问时,就会在请求头的 cookie 字段上附带 cookie 信息,这样服务器就可以识别是谁在访问了,但是 cookie 存在缺陷:

  • 不安全—本地保存,容易被篡改

  • 大小受限,本身最大 4kb

    cookie 虽然在一定程度上解决了‘保持状态’的需求,但是我们希望有一种新的技术可以

    克服 cookie 缺陷,这种技术就是 session

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

(1)、爬虫案列:开心网
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 伪装,这就是代理的基本原理

(1)、设置代理爬取
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、非结构化数据:

定义:就是没有固定的结构。各种文档,图片,视频或者音频等等…

特点:非结构化数据

处理方式:对于这类数据,我们一般直接整体进行存储,而且一般存储为二进制形式

(1)、json格式

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
}
(2)、处理json数据的两种方式

json 模块有两个方法 dumps 和 loads 方法,其参数和返回值如下:

(1)将 python 类型转为 json 字符串类型:

json 字符串= json.dumps(python 类型)

(2)将 json 字符串类型转为 Python 类型(python 的 list 或者字典:

Python 的 list 或者字典 = json.loads(json 的字符串格式)

(3)爬虫案例:高德地图
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()

四、正则表达式

正则表达式,又称规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本

1、元字符
元字符 含义
^ 匹配行首
$ 匹配行尾
重复匹配 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
2、python中正则表达式模块—re

在 Python 中,我们可以使用内置的 re 模块来使用正则表达式。有一点需要特别注意 的是,正则表达式使用对特殊字符进行转义,所以如果我们要使用原始字符串,只需加一个 r 前缀

  • re 模块的一般使用步骤如下:

第一步:使用 compile()函数将正则表达式的字符串形式编译为一个 Pattern 对象

第二步:通过 Pattern 对象提供的一系列方法对文本进行匹配查找,获得匹配结果,一 个 Match 对象

第三部:最后使用 Match 对象提供的属性和方法获得信息,根据需要进行其他的操作

  • compile 函数

compile 函数用于编译正则表达式,生成一个 Pattern 对象,它的一般使用形式如下:

在上面,我们已将一个正则表达式编译成 Pattern 对象,接下来,我们就可以利用 pattern 的 一系列方法对文本进行匹配查找了

Pattern 对象的一些常用方法主要有:

方法 描述
match 从起始位置开始查找,一次匹配
search 从任何位置开始查找,一次匹配
findall 全部匹配,返回列表
finditer 全部匹配,返回迭代器
split 分割字符串,返回列表
sub 替换
(1)、match方法

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))

(2)、search方法

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)
(3)、findall方法

其中,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']
(4)、finder方法

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)
(5)、split方法

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 用于指定最大分割次数,不指定将全部分割

(6)、sub方法

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 用于指定最多替换次数,不指定时全部替换

(7)、匹配中文

在某些情况下,我们想匹配文本中的汉字,有一点需要注意的是,中文的 unicode 编码

范围主要在[u4e00-u9fa5],这里说主要是因为这个范围并不完整,比如没有包括全角(中文)标点,不过,在大部分情况下,应该是够用的

假设现在想把字符串 title = ‘你好,hello,世界’ 中的中文提取出来,可以这么做:

import re

title = '您好,hellp,世界'
pattern = re.compile('[\u4e00-\u9fa5]+')
result = pattern.findall(title)
print(result)  # ['您好', '世界']
(8)、re.S 在正则中的作用

正则表达式中,“.”的作用是匹配除“\n”以外的任何字符,也就是说,它是在一行中进行 匹配。这里的“行”是以“\n”进行区分的。a 字符串有每行的末尾有一个“\n”,不过它不可见

如果不使用 re.S 参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始, 不会跨行。而使用 re.S 参数以后,正则表达式会将这个字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,在整体中进行匹配

五、贪婪模式与非贪婪模式

贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配( * );

非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配( ? );

Python 里数量词默认是贪婪的

六、正则表达式分组

分组在正则表达式中就是用()来表示的。一个括号就是一个分组。分组的作用主要有 以下两个:

(1)、筛选特点内容

通过给特点的内容加一个(),将来可以通过 group(1)方式取到这个括号内的东西。

(2)、反向引用:可以在同一个表达式中引用前面的分组表达式

(1)、爬虫案例:猫眼电影
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()
(2)、爬虫案例:淘宝电场商品信息爬取
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()
(3)、爬虫案例:股吧热门爬取
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)

    你可能感兴趣的:(网络爬虫,python)