spider -- 公交爬取實戰
這裡我爬取的是單個城市的公交資訊,有想法的朋友可以搞一下全國的
程式碼如下:
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)