这里我爬取的是单个城市的公交信息,有想法的朋友可以搞一下全国的
代码如下:
import requests
import time
from bs4 import BeautifulSoup
import json
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
def main():
url = 'http://zhengzhou.8684.cn/'
fp = open('公交.txt', 'w', encoding='utf8')
r = requests.get(url=url, headers=headers)
soup = BeautifulSoup(r.text, 'lxml')
# 查找得到所有的以数字开头的链接
num_list = soup.select('.bus_kt_r1 > a')
# 查找得到所有的以英文字母开头的链接
char_list = soup.select('.bus_kt_r2 > a')
# print(len(num_list),len(char_list))
href_list = num_list + char_list
for href in href_list:
href = url.rstrip('/') + href['href']
# print(href)
# 公交车
r = requests.get(url=href, headers=headers)
soup = BeautifulSoup(r.text, 'lxml')
bus_list = soup.select('#con_site_1 > a')
for bus in bus_list:
bus_href = url.rstrip('/') + bus['href']
# print(bus_href)
r = requests.get(url=bus_href, headers=headers)
soup = BeautifulSoup(r.text, 'lxml')
# 线路名称
route_name = soup.select('.bus_i_t1 > h1')[0].string
print('正在爬取---%s---...' % route_name)
# 运行时间
run_time = soup.select('.bus_i_content > p')[0].string.lstrip('运行时间:')
# 票价信息
price_info = soup.select('.bus_i_content > p')[1].string.lstrip('票价信息:')
# 公交公司
company = soup.select('.bus_i_content > p > a')[0].string
# 更新时间
update_time = soup.select('.bus_i_content > p')[-1].string.lstrip('最后更新:')
# 上行总站数
bus_top = soup.select('.bus_line_top > span')[0].text.strip('共站').strip()
# print(bus_top)
num = int(bus_top)
# 总站牌数
bus_line_sites = soup.select('.bus_line_site > .bus_site_layer > div > a')
# 上行站牌数
bus_line_site_top = bus_line_sites[:num]
up_name_list = []
for oa in bus_line_site_top:
up_name_list.append(oa.string)
# 下行总站数
bus_down = len(bus_line_sites) - num
# print(bus_down)
# 下行站牌数
bus_line_site_down = bus_line_sites[num:]
down_name_list = []
for oa in bus_line_site_down:
down_name_list.append(oa.string)
# 保存到字典
item = {
'线路名称': route_name,
'运行时间': run_time,
'票价信息': price_info,
'公交公司': company,
'更新时间': update_time,
'上行个数': bus_top,
'上行站牌': up_name_list,
'下行个数': bus_down,
'下行站牌': down_name_list,
}
string = json.dumps(item, ensure_ascii=False)
fp.write(string + '\n')
print('结束爬取---%s---' % route_name)
fp.close()
if __name__ == '__main__':
main()
timeout 异常处理:
import requests
import requests.exceptions
url = 'http://www.baidu.com/'
try:
# timeout的时间 是自己规定的最大耗时
r = requests.get(url, timeout=0.01) # 0.01秒系统反应不过来,所以抛出异常
except requests.exceptions.Timeout as e:
print(e)
requests 应用
requests是什么?urllib是什么。库,模拟浏览器发送http请求的,requests也是模拟发送http请求的
requests是对urllib的又一层封装,提供的接口非常的人性化、简单
http://docs.python-requests.org/zh_CN/latest/index.html
安装:pip install requests
发送get
定制头部
查看响应的内容
字符串内容 r.text
字节格式内容 r.content
响应url r.url
响应的状态码 r.status_code
响应头 r.headers
查看字符集 r.encoding 还可以定制字符集
发送post
r = requests.post(url=url, headers=headers, data=data)
ajax-post
r.json() === json.loads(r.text)
代理
proxies=proxy
cookie
是什么?由于http的无状态特性
如何使用会话机制,如何保存和携带cookie
s = requests.Session()
创建一个会话,再往下所有的请求都使用s.get() s.post()发送即可
异常
所有的异常都在 requests.exceptions 模块中
ConnectionError:URLError
HTTPError:HTTPError
Timeout:超时异常
通过添加timeout参数,来实现
证书处理
忽略证书 r = requests.get(url=url, verify=False)
import requests
url = 'https://www.baidu.com/s?'
data = {
'ie': 'utf8',
'wd': '安室奈美惠'
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
# data直接传递原生字典即可
r = requests.get(url=url, params=data, headers=headers)
'''
查看响应内容
字符串内容 r.text
字节格式内容 r.content
响应url r.url
响应状态码 r.status_code
'''
with open('百度.html', 'wb') as fp:
fp.write(r.content)