爬虫-Requests

Requests

安装

1
pip install requests
  • 官方文档
  • Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。

用来做什么?

urllib功能相似,Requests 允许你发送纯天然,植物饲养的 HTTP/1.1 请求,无需手工劳动。你不需要手动为 URL 添加查询字串,也不需要对 POST 数据进行表单编码。Keep-alive 和 HTTP 连接池的功能是 100% 自动化的,一切动力都来自于根植在 Requests 内部的 urllib3

get请求

  • 定制头部
    • data:是一个原生字典即可
    • requests.get(url, headers=headers, params=data)
  • 响应对象
    1
    2
    3
    4
    5
    6
    7
    r.text            字符串形式查看响应
    r.content 字节类型查看响应
    r.encoding 查看或者设置编码类型
    r.status_code 查看状态码
    r.headers 查看响应头部
    r.url 查看所请求的url
    r.json() 查看json格式数据
  • 示例1:不带参数的get
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import requests

    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }


    def main():
    url = 'https://www.baidu.com/'
    r = requests.get(url=url, headers=headers)
    print(r)
    # print(r.encoding)
    # r.encoding = 'utf8'
    print(r.text)


    if __name__ == '__main__':
    main()

  • 示例2:带参数的get
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import requests

    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }


    def main():
    url = 'https://www.baidu.com/s?'
    data = {
    'ie': 'utf8',
    'kw': '中国',
    }
    # parameters 参数
    r = requests.get(url=url, headers=headers, params=data)
    # 字符串形式查看响应
    print(r.text)
    # 字节类型查看响应
    print(r.content)
    # 查看或者设置编码类型
    print(r.encoding)
    # 查看状态码
    print(r.status_code)
    # 查看响应头部,字典格式
    print(r.headers)
    # 查看所请求的url
    print(r.url)
    # 把结果写入到文件中
    with open('baidu.html', 'wb')as fp:
    fp.write(r.content)


    if __name__ == '__main__':
    main()

post请求

  • 必应翻译
  • formdata: 是一个原生字典即可
  • r = requests.post(url=url, headers=headers, data=formdata)
  • 示例:post请求
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import requests

    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }


    def main():
    url = 'https://cn.bing.com/tlookupv3?isVertical=1&&IG=0E3F5DBC7C494B948709B072893BAC89&IID=translator.5028.11'
    formdata = {
    'from': 'en',
    'to': 'zh-Hans',
    'text': 'wolf',
    }
    r = requests.post(url=url, headers=headers, data=formdata)
    # 查看json格式数据
    print(r.json())


    if __name__ == '__main__':
    main()

ajaxgetpost

  • 和上面的是一样的

代理

  • r = requests.get(url, headers=headers, proxies=proxies)
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import requests

    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
    }


    def main():
    url = 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=ip'
    # 代理
    proxies = {
    'http': 'http://123.101.207.231:9999'
    }
    r = requests.get(url, headers=headers, proxies=proxies)
    with open('daili.html', 'wb')as fp:
    fp.write(r.content)


    if __name__ == '__main__':
    main()

  • 实现人人登录
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    import requests

    # 如果碰到会话相关的问题,要首先创建一个会话
    # 往下所有的操作都通过s进行访问 s.get s.post
    s = requests.Session()

    post_url = 'http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2018561026257'
    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
    }
    formdata = {
    'email': '17701256561',
    'icode': '',
    'origURL': 'http://www.renren.com/home',
    'domain': 'renren.com',
    'key_id': '1',
    'captcha_type': 'web_login',
    'password': '7b456e6c3eb6615b2e122a2942ef3845da1f91e3de075179079a3b84952508e4',
    'rkey': '44fd96c219c593f3c9612360c80310a3',
    'f': 'https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dm7m_NSUp5Ri_ZrK5eNIpn_dMs48UAcvT-N_kmysWgYW%26wd%3D%26eqid%3Dba95daf5000065ce000000035b120219',
    }

    r = s.post(url=post_url, headers=headers, data=formdata)

    # print(r.text)

    get_url = 'http://www.renren.com/960481378/profile'
    r = s.get(url=get_url, headers=headers)

    print(r.text)

chinaunix

  • 登录的思路是:先get获取登录所需要的一些参数,再post登录,再get访问登录后的页面
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    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/85.0.4183.83 Safari/537.36'
    }

    # 创建会话
    s = requests.Session()


    def main():
    # 访问登录页面,获取登录所需要的一些参数
    get_url = 'http://account.chinaunix.net/login/?url=http%3A%2F%2Fbbs.chinaunix.net%2Fforum.php'
    r = s.get(url=get_url, headers=headers)
    # 生成soup对象,获取_token值
    soup = BeautifulSoup(r.text, 'lxml')
    # 通过属性选择器获取对应的值
    _token = soup.select('input[name=_token]')[0]['value']
    # print(_token)

    # 向指定的post发送请求
    post_url = 'http://account.chinaunix.net/login/login'
    formdata = {
    'username': 'xxx',
    'password': 'xxx',
    '_token': _token,
    '_t': '1598882760234',
    }
    r = s.post(url=post_url, headers=headers, data=formdata)
    print(r.text)

    # 访问登录后的页面
    info_url = 'http://bbs.chinaunix.net/home.php?mod=space&uid=69983003&do=profile'
    r = s.get(url=info_url, headers=headers)
    with open('info.html', 'wb')as fp:
    fp.write(r.content)


    if __name__ == '__main__':
    main()

公交爬取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import time
import json
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/85.0.4183.83 Safari/537.36'
}

# 列表用来保存所有的线路信息
items = []


def parse_navigation():
url = 'https://hangzhou.8684.cn/'
r = requests.get(url, headers=headers)
# 解析内容,获取所有的导航链接
tree = etree.HTML(r.text)
# 查找以数字开头的所有链接
number_href_list = tree.xpath('//div[@class="bus-layer depth w120"]/div[1]/div/a/@href')
# 查找以字母开头的所有链接
char_href_list = tree.xpath('//div[@class="bus-layer depth w120"]/div[2]/div/a/@href')
# 将需要爬取的所有连接返回
return number_href_list + char_href_list


def parse_sanji_route(content):
tree = etree.HTML(content)
# 获取公交线路信息
bus_number = tree.xpath('//h1/text()')[0]
print(f'开始爬取{bus_number}公交信息......')
# 获取运行时间
run_time = tree.xpath('//ul[@class="bus-desc"]/li[1]/text()')[0].replace('运行时间:', '')
# 获取票价信息
ticket_info = tree.xpath('//ul[@class="bus-desc"]/li[2]/text()')[0].replace('票价信息:', '')
# 获取更新时间
update_time = tree.xpath('//ul[@class="bus-desc"]/li[4]/text()')[0].replace('最后更新:', '')
# 获取上行总站数
up_total = tree.xpath('//div[@class="total"]/text()')[0]
# 获取上行所有站名
up_site_list = tree.xpath('//div[@class="bus-lzlist mb15"][1]/ol/li/a/text()')
# 获取下行总站数
try:
down_total = tree.xpath('//div[@class="total"]/text()')[1]
except IndexError as e:
print(e)
down_total = 'None'
down_site_list = []
else:
# 获取下行所有站名
down_site_list = tree.xpath('//div[@class="bus-lzlist mb15"][2]/ol/li/a/text()')
# 将每一条公交的线路信息存放到字典中
item = {
'线路名': bus_number,
'运行时间': run_time,
'票价信息': ticket_info,
'更新时间': update_time,
'上行站数': up_total,
'上行站点': up_site_list,
'下行站数': down_total,
'下行站点': down_site_list,
}
item = json.dumps(item, ensure_ascii=False)
items.append(item)
print(f'{bus_number}公交信息爬取结束......')
print('=' * 60)
time.sleep(0.5)


def parse_erji_route(content):
tree = etree.HTML(content)
# 获取每一个线路
route_list = tree.xpath('//div[@class="list clearfix"]/a/@href')
# 遍历上面这个列表
for route in route_list:
route = 'https://hangzhou.8684.cn' + route
print(route)
r = requests.get(url=route, headers=headers)
# 解析内容,获取每一路公交的详细信息
parse_sanji_route(r.text)


def parse_erji(navi_list):
# 遍历上面的列表,依次发送请求,解析内容,获取每一个页面所有的公交路线url
for first_url in navi_list:
url = 'https://hangzhou.8684.cn' + first_url
print(url)
r = requests.get(url, headers=headers)
# 解析内容,获取每一路公交的详细url
parse_erji_route(r.text)


def main():
# 爬取第一页所有的导航链接
navi_list = parse_navigation()
# 爬取二级页面,需要找到以1开头的所有公交路线
parse_erji(navi_list)
# 写入文件中
with open('杭州公交.txt', 'a', encoding='utf8')as fp:
fp.write(str(items))


if __name__ == '__main__':
main()

验证码

登录古诗文网

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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/85.0.4183.83 Safari/537.36'
}


def download_code(s):
url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
r = s.get(url=url, headers=headers)
soup = BeautifulSoup(r.text, 'lxml')
# 得到图片链接
image_src = 'https://so.gushiwen.cn' + soup.find('img', id='imgCode')['src']
print(image_src)
r_image = s.get(url=image_src, headers=headers)
with open('code.png', 'wb')as fp:
fp.write(r_image.content)
# 查找表单所需要的两个参数
__VIEWSTATE = soup.find('input', id='__VIEWSTATE')['value']
__VIEWSTATEGENERATOR = soup.find('input', id='__VIEWSTATEGENERATOR')['value']
return __VIEWSTATE, __VIEWSTATEGENERATOR


def login(__VIEWSTATE, __VIEWSTATEGENERATOR, s):
post_url = 'https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx'
# 提示用户输入验证码
code = input('哥们,麻烦你输入验证码:')
formdata = {
'__VIEWSTATE': __VIEWSTATE,
'__VIEWSTATEGENERATOR': __VIEWSTATEGENERATOR,
'from': 'http://so.gushiwen.cn/user/collect.aspx',
'email': 'xxx',
'pwd': 'xxx',
'code': code,
'denglu': '登录',
}
r = s.post(url=post_url, headers=headers, data=formdata)
with open('gushi.html', 'wb')as fp:
fp.write(r.content)


def main():
# 创建会话
s = requests.Session()
# 下载验证码到本地
__VIEWSTATE, __VIEWSTATEGENERATOR = download_code(s)
# 向post地址发送请求
login(__VIEWSTATE, __VIEWSTATEGENERATOR, s)


if __name__ == '__main__':
main()

Tesseract

简介

  • Tesseract最初是在1985年至1994年之间在布里斯托惠普实验室和科罗拉多州格里利惠普公司开发的,1996年进行了一些更改以移植到Windows,并在1998年进行了一些C ++化。2005年Tesseract开放由HP采购。自2006年以来,它是由Google开发的。
  • 光学识别,但是不要对它期望太高。只能识别简单的验证码。

安装

  1. pip install pytesseract
  2. pip install pillow
  3. 下载Tesseract OCR,密码:6uj7
  4. 安装Tesseract OCR
  5. 要从任何位置访问tesseract-OCR,可能必须将tesseract-OCR二进制文件所在的目录添加到Path变量中(可能是)C:\Program Files\Tesseract-OCR

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pytesseract
from PIL import Image
from PIL import ImageEnhance

# 打开图片
img = Image.open('sg3p.png')

img = img.convert('RGB')
enhancer = ImageEnhance.Color(img)
enhancer = enhancer.enhance(0)
enhancer = ImageEnhance.Brightness(enhancer)
enhancer = enhancer.enhance(2)
enhancer = ImageEnhance.Contrast(enhancer)
enhancer = enhancer.enhance(8)
enhancer = ImageEnhance.Sharpness(enhancer)
img = enhancer.enhance(20)

# 转化为灰度图片
img = img.convert('L')
# img.show()

# 二值化处理
threshold = 140
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
out = img.point(table, '1')
# out.show()
# exit()
img = img.convert('RGB')
# 识别图片
print(pytesseract.image_to_string(img))

打码平台

  • 打码兔、云打码
  • 云打码为例
    1
    2
    3
    注册普通用户、开发者
    然后下载PythonHTTP接口示例
    将里面的username\password\appid\appkey修改即可
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    from YDMHTTPDemo3 import YDMHttp

    # 普通用户的用户名和密码
    # 用户名
    username = 'username'
    # 密码
    password = 'password'

    # 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得! 就是软件代码,需要在我的软件中添加软件
    appid = xxxx

    # 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
    appkey = 'appkey'

    # 图片文件
    filename = 'sg3p.png'

    # 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html
    codetype = 1004

    # 超时时间,秒
    timeout = 60

    # 检查
    if (username == 'username'):
    print('请设置好相关参数再测试')
    else:
    # 初始化
    yundama = YDMHttp(username, password, appid, appkey)

    # 登陆云打码
    uid = yundama.login();
    print('uid: %s' % uid)

    # 查询余额
    balance = yundama.balance();
    print('balance: %s' % balance)

    # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
    cid, result = yundama.decode(filename, codetype, timeout);
    print('cid: %s, result: %s' % (cid, result))

百度文字识别

  1. 简介

    基于百度云的文字识别接口,需要申请百度云账号,然后再创建文字识别应用,最后获得需要的参数AppID、API Key和Secret Key

  2. 百度云OCR识别申请教程

  3. 安装

    1
    pip install baidu-aip
  4. SDK文档

  5. 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    from aip import AipOcr

    # 你的 APPID AK SK
    APP_ID = '你的 App ID'
    API_KEY = '你的 Api Key'
    SECRET_KEY = '你的 Secret Key'

    client = AipOcr(APP_ID, API_KEY, SECRET_KEY)


    # 读取图片
    def get_file_content(filePath):
    with open(filePath, 'rb') as fp:
    return fp.read()


    def main():
    # 读取图片
    image = get_file_content('4.png')
    # 调用通用文字识别, 图片参数为本地图片
    print(client.basicGeneral(image))
    # 调用通用文字识别(高精度版)
    print(client.basicAccurate(image))


    if __name__ == '__main__':
    main()

  6. 通用文字识别 返回示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "log_id": 2471272194,
    "words_result_num": 2,
    "words_result":
    [
    {"words": " TSINGTAO"},
    {"words": "青島睥酒"}
    ]
    }
  7. 资费说明

    API 状态 调用量限制
    通用文字识别(标准版) 免费使用 50000次/天免费
    通用文字识别(高精度版) 免费使用 500次/天免费

下载视频

示例1:测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import os
import requests
import urllib.parse
import urllib.request

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0'
}


def main():
url = 'http://v3-tt.ixigua.com/8046ab9f9760d55a5a9b72eb77ebc9dd/5f4e236a/video/tos/hxsy/tos-hxsy-ve-0004/b9916fb9b88242cca7d48fe60b961436/?a=0&br=1269&bt=423&cr=0&cs=0&cv=1&dr=0&ds=1&er=&l=20200901172947010198058228273EB204&lr=&mime_type=video_mp4&qs=0&rc=MzN2c3c0cjkzbTMzNzczM0ApNTg8aDpoPGU4Nzg3ZmY0ZWdrcGQwZTZrL2tfLS0uLTBzczU0Mi9iLWBfYWNhMGM1MzI6Yw%3D%3D&vl=&vr='
if not os.path.exists('shipin'):
os.mkdir('shipin')
# 下载视频
urllib.request.urlretrieve(url, 'shipin/1.mp4')

# 下载视频
r = requests.get(url, headers=headers)
with open('shipin/11.mp4', 'wb')as fp:
fp.write(r.content)


if __name__ == '__main__':
main()

这两种方式都可以下载视频。

示例2:实操

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# 使用selenium+xpath+requests下载视频
# http://365yg.com/

'''
首先向365yg.com发送请求
获取响应,解析响应,将里面所有的标题链接获取到
依次向每个标题链接发送请求
获取响应,解析响应,获取video标签的src属性
向src属性发送请求,获取响应,将内容保存到本地即可
'''
import os
import time
import json
import base64
import urllib.request

import requests
from lxml import etree
from selenium import webdriver
from selenium.webdriver.firefox.options import Options

'''
接口信息:
http://365yg.com/xigua/feed/?ChannelID=6797027941&Count=10&UseHQ=true
'''

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0'
}

# 创建一个参数对象,用来控制chrome以无界面模式打开
firefox_options = Options()
# 以无界面模式运行Chrome
firefox_options.add_argument('--headless')
# --disable-gpu 主要是为了屏蔽现阶段可能触发的错误
firefox_options.add_argument('--disable-gpu')
# 设置界面最大化
firefox_options.add_argument('--start-maximized')


def handle_href(title_url, title):
if not os.path.exists('videos'):
os.mkdir('videos')
filename = 'videos/' + title.replace('?', '') + '.mp4'
# 通过selenium来进行解决
if 'toutiao' in title_url:
# 模拟创建一个浏览器对象,然后通过对象去操作浏览器
browser = webdriver.Firefox(options=firefox_options)
browser.get(title_url)
time.sleep(2)
# 获取源码,生成tree对象,然后查找video里面的src属性
tree = etree.HTML(browser.page_source)
browser.save_screenshot('video.png')
browser.quit()
# 获取src属性
video_src = tree.xpath('//video/@src')[0]
if 'blob:' in video_src:
print(video_src)
print('分段视频跳过......')
else:
video_src = 'https:' + video_src
print(video_src)
# 下载视频
r = requests.get(url=video_src, headers=headers)
print(f'{title}开始下载......')
with open(filename, 'wb')as fp:
fp.write(r.content)
print(f'{title}结束下载......')
else:
print(f'{title}开始下载......')
urllib.request.urlretrieve(title_url, filename)
print(f'{title}结束下载......')
print('=' * 60)


def handle_title():
# 将捕获接口拿过来
url = 'http://365yg.com/xigua/feed/?ChannelID=6797027941&Count=10&UseHQ=true'
r = requests.get(url, headers=headers)
# 获取数据
data = r.json()['Data']
# print(data)
print(f'该页共{len(data)}条数据!')
for item in data:
# 获取base64加密后的内容
b64 = item['raw_data']
# print(b64)
# 解密base64加密的内容
content = base64.b64decode(b64).decode('utf8')
# print(content)
# 将json数据转化为python对象
obj = json.loads(content)
# 获取标题
title = obj['title']
print(title)
# 获取标题链接
title_url = obj['article_url']
print(title_url)
print('*' * 50)
handle_href(title_url, title)


def main():
page_number = int(input('请输入想爬取多少页:'))
for page in range(page_number):
# 解析首页,返回所有的标题链接
handle_title()
time.sleep(1)


if __name__ == '__main__':
main()