1. 程式人生 > >spider -- 公交爬取實戰

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)