ScienceDirect內容爬蟲

小豬玥發表於2021-07-21

爬蟲違法,本貼方法只限於個人對資料的分析使用,其爬蟲程式已作相關設定,以減小伺服器壓力。不適宜長期使用。


 

一、前期準備

1、使用chrome開啟ScienceDirect網站(https://www.sciencedirect.com),在搜尋框輸入想要查詢的關鍵詞再點選放鏡按鈕搜尋,比如:extreme water level

2、在新跳轉搜尋結果列表頁面開啟瀏覽器的開發者工具(右鍵點選-檢視網頁原始碼),搜尋我們想要的內容,比如文章標題,看看是否能搜到。如果能搜尋到表明我們需要的內容在html中,如果沒有,那麼這個網站很可能採用前後端分離的技術,我們所需要的資料很可能在json中,這種情況則需要找介面來獲取。

 

 3、通過檢視原始碼發現沒有我們想要的資料。那麼再試試看是否在json中,方法是在搜尋列表頁面右鍵-檢查-網路-重新整理瀏覽器以抓包-找出可能的資料包(檢視preview標

 

 得到介面為:https://www.sciencedirect.com/search/api

二、開始程式獲取

1、首先匯入必要庫(有的庫在本次例項中不一定用上)

1 import requests
2 import json,re,os
3 from bs4 import BeautifulSoup
4 from urllib.parse import quote

2、實際上這裡還可以通過html的方式,嘗試看看能否獲取到資料

第1行:我們查詢的關鍵詞

第2行:前半部分的網址是搜尋列表頁面的地址,其中的quote(key)是將其轉為瀏覽器中的編碼格式。

第3行:是為了防止反爬蟲而設定的

第7行:獲取html資料

第8行:防止因為編碼問題出現亂碼情況

第9行:用BeautifulSoup解析html,方便對資料切片,因為html為字串型別資料,不太方便定位資料位置

第10行:定位標題內容的類位置,(通過上面的元素標籤中定位的方法,找出標題內容對應的類位置)

第11行:列印檢視是否有內容,結果為一個空的列表,表明沒有資料

 1 key = 'extreme water level'
 2 url = 'https://www.sciencedirect.com/search?qs='+quote(key)
 3 headers = {
 4     'cookie': 'search_ab=%7B%221%22%3A23%7D; sd_search=eyJhdXRoSGlzdG9yeSI6eyJwcmV2aW91c0N1c3RvbWVyIjp0cnVlLCJwcmV2aW91c0xvZ0luIjpmYWxzZX19.uRn%2Fj4TgvLEmApohDX%2FmiA2G8WsVm1yImoH3Mot2ZxY; EUID=5a74edc0-f0c2-4918-a17a-66731930dc86; id_ab=AEG; sd_session_id=012e12f879e18845c30b0a9170ac4912ea42gxrqa; acw=012e12f879e18845c30b0a9170ac4912ea42gxrqa%7C%24%7C7655A62AC882D5B269BB32EC1CC1FA66BFB036F913742AB6843F53CFFBCDE26B054E9D90CFD61FB88103979492FFB4EA4ACF86F54EABC9A63FBA44D1BD4E4F2EAFE9C31A29ED2080B6DA1F7CB1786ABB; ANONRA_COOKIE=AC4FAB305B9736FF9E8F009F581F56B5B5BD34D45FE243EBB2FAC7271249E9F096D5E4A555833E115E4A5D76175BE9945F2CB26604FED07A; has_multiple_organizations=false; __cf_bm=6ee31fd3af4f560d4d5d0906c971f77575face0b-1626413997-1800-AXcVXU6yJAqWmH+hPTzES7cu4h8ITDKR9SaZsBJK1MgUadBZjqCsmSDCdmc0zHagqGT1PM9GDgr1k0mS1T76Gb6SE5IQHj24mXluDvZ+eHDK; fingerPrintToken=e1fe7953298449ebbfc118c358a167eb; AMCVS_4D6368F454EC41940A4C98A6%40AdobeOrg=1; AMCV_4D6368F454EC41940A4C98A6%40AdobeOrg=-1124106680%7CMCIDTS%7C18824%7CMCMID%7C12297380359548630414269390810591070709%7CMCAID%7CNONE%7CMCOPTOUT-1626421207s%7CNONE%7CMCAAMLH-1627018807%7C11%7CMCAAMB-1627018807%7Cj8Odv6LonN4r3an7LhD3WZrU1bUpAkFkkiY1ncBR96t2PTI%7CMCCIDH%7C-582229202%7CMCSYNCSOP%7C411-18831%7CvVersion%7C5.2.0; s_pers=%20v8%3D1626414014787%7C1721022014787%3B%20v8_s%3DLess%2520than%25201%2520day%7C1626415814787%3B%20c19%3Dsd%253Asearch%253Aresults%253Acustomer-standard%7C1626415814789%3B%20v68%3D1626414007149%7C1626415814795%3B; MIAMISESSION=deb5a6e8-4414-46d9-b806-916bfbb38018:3803866821; SD_REMOTEACCESS=eyJhY2NvdW50SWQiOiI2MjYyNiIsInRpbWVzdGFtcCI6MTYyNjQxNDAyMTI4NX0=; s_sess=%20s_cpc%3D1%3B%20s_cc%3Dtrue%3B%20s_ppvl%3D%3B%20c21%3Dqs%253Dwater%2520level%3B%20e13%3Dqs%253Dwater%2520level%253A1%3B%20c13%3Drelevance-desc%3B%20e41%3D1%3B%20s_ppv%3Dsd%25253Asearch%25253Aresults%25253Acustomer-standard%252C18%252C18%252C801%252C813%252C801%252C1368%252C912%252C2%252CP%3B',
 5     'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.67'
 6 }
 7 html = requests.get(url,headers=headers)
 8 html.encoding=html.apparent_encoding
 9 soup = BeautifulSoup(html.text,'lxml')
10 results = soup.select('.ResultItem.col-xs-24.push-m')
11 print(results)

3、通過json方法獲取

第6行:引數需要在找到的包的Header標籤中獲取

再列印html可以發現存在資料,那麼可以成功獲取資料了

 1 key = 'extreme water level'
 2 url = 'https://www.sciencedirect.com/search/api'
 3 headers = {
 4     'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70'
 5 }
 6 params = {
 7     'qs': key,
 8     't': '9NwQbtENcKA3t6ec13yc3J0oVqdNg1DW8FkZ4fWmlbcNo377tsI2SJxXzbXzVwMMUWW%2BAzqQnWkVBhGgXl1YEZB2ZEiI4q7ewQjm6xR64IyvpCFFhj%2FhSSA7wBjoACIKvKdDbfVcomCzYflUlyb3MA%3D%3D',
 9     'hostname': 'www.sciencedirect.com'
10 }
11 html = requests.get(url,headers=headers,params=params)

4、以下是完整程式碼:

為了防止給伺服器造成壓力,這裡我們對for迴圈設定間隔一定的時間,首先匯入相關包

import time
import random

第12行:是將json格式轉化為python中的字典格式

第13行:在2-6(不包括6)之間隨機生成一個整數,time.sleep(**),表示程式暫停,括號中的數值表示暫停的時間(秒)

for迴圈中的標題、出版日等欄位都是在網頁json包中的preview中查詢到的。

 1 key = 'extreme water level'
 2 url = 'https://www.sciencedirect.com/search/api'
 3 headers = {
 4     'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70'
 5 }
 6 params = {
 7     'qs': key,
 8     't': '9NwQbtENcKA3t6ec13yc3J0oVqdNg1DW8FkZ4fWmlbcNo377tsI2SJxXzbXzVwMMUWW%2BAzqQnWkVBhGgXl1YEZB2ZEiI4q7ewQjm6xR64IyvpCFFhj%2FhSSA7wBjoACIKvKdDbfVcomCzYflUlyb3MA%3D%3D',
 9     'hostname': 'www.sciencedirect.com'
10 }
11 html = requests.get(url,headers=headers,params=params)
12 data = json.loads(html.text)['searchResults']
13 time.sleep(random.randint(2,6))
14 for d in data:
15     article_type = d['articleTypeDisplayName']
16     print('文章型別:',article_type)
17     publication_date = d['publicationDate']
18     print('出版日:',publication_date)
19     journal_name = d['sourceTitle']
20     print('期刊:',journal_name)
21     title = d['title']
22     print('標題:',title.replace("<em>",'').replace("</em>",''))
23     doi = d['doi']
24     print('doi號:',doi)
25     # 獲取作者列表
26     authors = d['authors']
27     author_lists = []
28     for au in authors:
29         author_lists.append(au['name'])
30     print('作者:',author_lists)
31     url2 = d['pdf']['downloadLink']
32     print('下載地址:')
33     print('https://www.sciencedirect.com'+str(url2))
34     url3 = d['pdf']['getAccessLink']
35     innerUrl = 'https://www.sciencedirect.com'+str(url3)
36     headers = {
37         'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70'
38     }
39     html = requests.get(innerUrl,headers=headers)
40     soup = BeautifulSoup(html.text,'lxml')
41     data = soup.select('.abstract.author div p')
42     abstract = ''
43     for d in data:
44         abstract += d.text+'\n'
45     print('摘要:')
46     print(abstract)
47     print('----'*10)
48     time.sleep(random.randint(2,6))

最後是輸入的結果,當然還可以寫一個儲存程式,將爬蟲到的資料儲存下來

相關文章