1. 程式人生 > >Python之爬蟲有感(一)

Python之爬蟲有感(一)

urllib.request.Request('URL',headers = headers)
User-Agent 是爬蟲和反爬蟲鬥爭的第一步,傳送請求必須帶User—Agent
使用流程:
    1、建立請求物件
        request = urlllib.request.Request('url'......)
    2、傳送請求獲取響應物件
        response = urllib.request.urlopen(request)

    3、獲取響應內容
        html = response.read().deconde('utf-8')

為什麼要使用User—Agent呢?如果沒有這個就對網頁進行爬取,當爬取大量資料短時間大量訪問網頁那邊就會知道你這邊是一個程式,就可以進行遮蔽,使用User-Agent能夠讓那邊認為你這邊的爬蟲是一個瀏覽器對其進行訪問,不會攔截,當然如果就一個User-Agent短時間訪問多次也是會被攔截,此時解決問題的方法是使用多個User-Agent,每次訪問網頁都隨機選取一個User-Agent,這樣就可以解決該問題。

簡單的示例,使用上面的方法爬取百度首頁內容:

import urllib.request

url = "https://www.baidu.com/"

headers = {'User-Agent': '自己找一個Uer-Agent'}

#1、建立請求物件
req = urllib.request.Request(url, headers=headers)

#2、獲取響應物件
res = urllib.request.urlopen(req)

#3|響應物件read().decode('utf-8')
html = res.read().decode('utf-8')
print(html)

如果要爬取一些複雜的網頁,就需要對網頁進行分析。

比如說對騰訊招聘進行爬取,首先騰訊招聘網頁是一個動態網頁,簡單方式爬取不了,那我們找到這個網頁的json網頁如下:

https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1563246818490&countryId=&cityId=&bgIds=&productId=&categoryId=40001001,40001002,40001003,40001004,40001005,40001006&parentCategoryId=&attrId=&keyword=&pageIndex=0
&pageSize=10&language=zh-cn&area=cn
網頁獲得的結果是這樣的:

這樣看起來很難受,所以用一個外掛JSON View(chrome瀏覽器),重新載入後格式為:

這樣看起來就舒服多了,而且都是字典格式以及列表,找到我們想要的資料就更加簡單了。

我們可以修改pageIndex這個錨點的值跳轉到不同頁面,對多個頁面進行爬取。
話不多說,直接先上程式碼:
import urllib.request
import json

beginURL = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1563246818490&countryId=&cityId=&bgIds=&productId=&categoryId=40001001,40001002,40001003,40001004,40001005,40001006&parentCategoryId=&attrId=&keyword=&pageIndex='
offset = 0
endURL = '&pageSize=10&language=zh-cn&area=cn'
start_urls = beginURL + str(offset) + endURL
headers = {'User-Agent': '自己找一個User-Agent'}

while True:
    if offset < 2:
        offset += 1
    else:
        break

    html = urllib.request.urlopen(start_urls, headers=headers)
    result = json.loads(html.read())

    position = {}
    L = []
    for i in range(len(result['Data']['Posts'])):
        position['職位名稱'] = result['Data']['Posts'][i]['RecruitPostName']
        position['最近公佈時間'] = result['Data']['Posts'][i]['LastUpdateTime']
        position['工作地點']  = result['Data']['Posts'][i]['CountryName'] + result['Data']['Posts'][0]['LocationName']
        position['職位內容'] = result['Data']['Posts'][i]['Responsibility']
        position['工作連結'] = result['Data']['Posts'][i]['PostURL']
        L.append(position)

    print(L)
    with open('TencentJobs.json', 'a', encoding='utf-8') as fp:
        json.dump(L, fp, ensure_ascii=False)

我的思路大致是這樣的:

首先從一個網頁裡面爬取到自己想要的資料,將第一個網頁加載出來,html = urllib.request.urlopen(start_urls, headers=headers)  result = json.loads(html.read()),將start-urls換成第一個網頁的url就可以了,通過程式將網頁得到的結果放在result裡,然後從第一個網頁進行分析,發現它裡面的內容都是字典還有一個列表,那麼通過字典和列表的索引方式找到我們想要的資料。例如,獲得職位名稱可以使用result['Data']['Posts'][i]['RecruitPostName'],再用一個一個position字典進行儲存,後面依次類推。

將所有的字典都儲存到一個列表L裡面,然後再將L內資料寫入到本地json檔案中。對於多頁面找到了錨點pageIndex,就通過一些手段每次某一頁面爬取完就更改pageIndex爬取下一頁。本程式通過更改offset的值,原網頁應該有203個頁面左右,我程式裡面只爬取了兩個頁面,可以自行更改。

好了,如果使用了scrapy框架就會體會到python爬蟲是多麼的方便了。