Python爬蟲(chóng)入門(mén)級(jí)項(xiàng)目

項(xiàng)目簡(jiǎn)介

由于最近調(diào)研文獻(xiàn)需要丧鸯,想查看KDD2017年的論文是否有相關(guān)的論文。但是KDD accept的論文有200+,要一篇篇去看太浪費(fèi)時(shí)間了角钩。于是想寫(xiě)個(gè)爬蟲(chóng)赚抡,爬取論文的abstract爬坑,然后Ctrl+F看下是否包含相關(guān)的keyword。 本來(lái)也想爬取每篇論文的keywords涂臣,但是提供的網(wǎng)頁(yè)中沒(méi)有這個(gè)內(nèi)容盾计,所以這里沒(méi)有爬取售担。最后爬取的內(nèi)容格式為:
<title, author, abstract, link>,其中l(wèi)ink是論文在acm library中的網(wǎng)址署辉。

注:建議先學(xué)習(xí)網(wǎng)易云課堂一個(gè)python網(wǎng)絡(luò)爬蟲(chóng)的教程族铆,免費(fèi),而且很短哭尝,里面涉及很多知識(shí)哥攘,對(duì)小白很有幫助。我使用的方法大多都是其中的材鹦。 鏈接:http://study.163.com/course/courseLearn.htm?courseId=1003285002#/learn/video?lessonId=1046324611&courseId=1003285002

用到的工具

Python 3.6(Anaconda虛擬環(huán)境)
requests献丑、BeautifulSoup、pandas侠姑、re包
 Chrome插件:selectorgadget

具體步驟

首先创橄,進(jìn)入kdd2017的網(wǎng)址,發(fā)現(xiàn)accepted paper在 http://www.kdd.org/kdd2017/accepted-papers中莽红,且該網(wǎng)址使用'GET'方法妥畏,所以利用requests包打開(kāi)該網(wǎng)址。代碼如下:

import requests
url = 'http://www.kdd.org/kdd2017/accepted-papers'
res = requests.get(url)
res.encoding = 'utf-8'  ##設(shè)置編碼

然后觀(guān)察我們需要的論文的CCS屬性安吁,利用selectorgadget可以方便的得到所有論文的CCS屬性為"#fitvid0 , .table-bordered a"醉蚁,所以我們可以用BeautifulSoup去定位到這些論文,并把結(jié)果存在papers變量中鬼店。

from bs4 import BeautifulSoup
soup = BeautifulSoup(res.text, 'html.parser')
papers = soup.select('#fitvid0 , .table-bordered a')

我們輸出papers中第一個(gè)元素看一下网棍,#注釋的部分為輸出結(jié)果:

print(papers[0])
#<a >Randomization or Condensation?: Linear-Cost Matrix Sketching Via Cascaded Compression Sampling</a>

我們發(fā)現(xiàn)結(jié)果中包含'href'屬性,這是論文的詳細(xì)描述妇智。之前http://www.kdd.org/kdd2017/accepted-papers中只包含論文的title和author滥玷。所以為了爬取具體的abstract,我們需要分別進(jìn)入每一篇論文的描述頁(yè)中巍棱。 使用如下代碼: papers[i]['href'],i為具體第i篇論文惑畴,我們使用for循環(huán)可以遍歷每一篇論文。

解析論文描述頁(yè)內(nèi)容

首先我們隨便找一篇論文航徙,查看網(wǎng)頁(yè)中包含哪些內(nèi)容:


image.png

網(wǎng)頁(yè)中包含 title, author, Abstract如贷,以及一個(gè)支持下載的按鈕。 其中該下載按鈕中包含一個(gè)url跳轉(zhuǎn)到具體的下載的acm library頁(yè)面到踏。所以我們接下來(lái)就對(duì)每個(gè)內(nèi)容進(jìn)行爬取杠袱。

Title

image.png

title內(nèi)容的爬取非常簡(jiǎn)單,我們利用Chrome自帶開(kāi)發(fā)者模式中元素審查發(fā)現(xiàn)它存在于<h3></h3>中窝稿,所以我們直接定位到該標(biāo)簽位置即可

title = soup.select('h3').text

Author

image.png

author內(nèi)容在<strong></strong>之中楣富,所以我們可以使用如下代碼提取作者信息。

author = soup.strong.text

注意:soup.strong會(huì)找出網(wǎng)頁(yè)中第一個(gè)strong標(biāo)簽的內(nèi)容讹躯,因?yàn)檫@里author的strong標(biāo)簽是第一個(gè)出現(xiàn)的菩彬,所以沒(méi)有關(guān)系。

Abstract

image.png

從圖中我們看到Abstract內(nèi)容在<p></p>中潮梯,但是骗灶,網(wǎng)頁(yè)中有很多的<p></p>標(biāo)簽,我們嘗試定位并輸出看一下:

image.png

爬取Abstract的難點(diǎn)主要有3點(diǎn):
1.我們發(fā)現(xiàn)輸出的結(jié)果中除了Abstract還有其他很多沒(méi)用的信息
2.Abstract的<p></p>不是第一個(gè)出現(xiàn)秉馏,無(wú)法使用類(lèi)似于author的方法耙旦。
3.有些論文的Abstract有2段,有些論文的Abstract只有1段萝究。
在這里免都,我們通過(guò)觀(guān)察每個(gè)論文的<p></p>的內(nèi)容的規(guī)律,發(fā)現(xiàn)內(nèi)容中:
第一個(gè)內(nèi)容帆竹,以及最后兩個(gè)內(nèi)容不是我們要的Abstract绕娘,其他中間的內(nèi)容就是Abstract。所以我們可以利用list的分片方法取出中間的內(nèi)容栽连。

abstract = []
    for a in soup.select('p')[1:-2]:
        abstract.append(a.text)
abstracts = ' '.join(abstract)##把多段的內(nèi)容合并成一段

Link

Link的提取是本項(xiàng)目最難的地方险领。我們直接審查元素?zé)o法定位到具體的url,而真正的url存在于<a></a>中


image.png

當(dāng)我們定位<a></a>標(biāo)簽時(shí)秒紧,會(huì)出現(xiàn)下面的情況绢陌。


image.png

我們發(fā)現(xiàn)會(huì)把網(wǎng)頁(yè)中所有鏈接的url都輸出了。我們需要從中選出真正指向acm library的url熔恢。在這里我們使用正則表達(dá)式進(jìn)行篩選脐湾。 因?yàn)閍cm library的網(wǎng)址的開(kāi)頭一定是‘dl.acm.org’,所以我們利用如下的方法對(duì)每個(gè)url進(jìn)行正則匹配叙淌,選擇出匹配的結(jié)果秤掌。

import re
link = []
for ele in soup.find_all("a"):
    m = re.search('.*dl.acm.org/.*', ele['href'])
    if m:
       link.append(m.group(0)) ##group(0)表示完整的匹配結(jié)果

我們嘗試對(duì)例子網(wǎng)頁(yè)進(jìn)行爬取,發(fā)現(xiàn)成功提取除了url鹰霍。

image.png

By the way:細(xì)心的朋友發(fā)現(xiàn)我這里link初始化成list机杜,在后面if語(yǔ)句中使用append添加元素。而不是直接用link = m.group(0)衅谷、這是因?yàn)樵趉dd2017 accepted 論文中有一篇論文不提供 download full paper的按鈕椒拗,所以對(duì)那篇論文進(jìn)行操作時(shí),m對(duì)象實(shí)際上不存在获黔。如果不先初始化link為list蚀苛,則會(huì)導(dǎo)致程序出錯(cuò)。

構(gòu)造解析函數(shù)

我們把上面四個(gè)內(nèi)容的爬取寫(xiě)進(jìn)一個(gè)函數(shù)中玷氏,函數(shù)的參數(shù)為論文的描述頁(yè)url堵未。

def paperDetail(url):
    detail = {}
    res = requests.get(url)
    res.encoding = 'UTF-8'
    soup = BeautifulSoup(res.text, 'html.parser')
    title = soup.h3.text
    author = soup.strong.text
    link = []
    for ele in soup.find_all("a"):
        m = re.search('.*dl.acm.org/.*', ele['href'])
        if m:
            link.append(m.group(0))
    abstract = []
    for a in soup.select('p')[1:-2]:
        abstract.append(a.text)
    abstracts = ' '.join(abstract)

    exp = lambda x: x[0] if len(x) > 0 else ''
    detail['link'] = exp(link)
    detail['author'] = author
    detail['title'] = title
    detail['abstract'] = abstracts
    return detail

循環(huán)解析所有論文

import pandas as pd
total_paper = []
    for i in range(len(papers)):
        print(i)
        one_paper = paperDetail(papers[i]['href'])
        total_paper.append(one_paper)

result = pd.DataFrame(total_paper)
result = result[['title','author','abstract','link']]
result.head()
result.to_csv('paper.csv')

至此,項(xiàng)目結(jié)束盏触。

總結(jié)

這是屬于最基本渗蟹、最簡(jiǎn)單的python爬蟲(chóng)項(xiàng)目块饺,只對(duì)靜態(tài)頁(yè)面進(jìn)行爬取,也沒(méi)有遇到發(fā)爬蟲(chóng)的困難雌芽。(本來(lái)還想進(jìn)入每篇論文的link爬取論文的doi,但是acm有反爬蟲(chóng)機(jī)制授艰,導(dǎo)致無(wú)法爬取,之后會(huì)研究如何反-反爬蟲(chóng))世落。
有大神對(duì)我其中任何一個(gè)步驟有建議的歡迎評(píng)論淮腾,有問(wèn)題也可留言。

致謝

感謝提供幫助的同學(xué)們:swy, cx, lck

完整代碼

import pandas as pd
from bs4 import BeautifulSoup
import requests
import re


def paperDetail(url):
    detail = {}
    res = requests.get(url)
    res.encoding = 'UTF-8'
    soup = BeautifulSoup(res.text, 'html.parser')
    title = soup.h3.text
    author = soup.strong.text
    link = []
    for ele in soup.find_all("a"):
        m = re.search('.*dl.acm.org/.*', ele['href'])
        if m:
            link.append(m.group(0))
    abstract = []
    for a in soup.select('p')[1:-2]:
        abstract.append(a.text)
    abstracts = ' '.join(abstract)

    exp = lambda x: x[0] if len(x) > 0 else ''
    detail['link'] = exp(link)
    detail['author'] = author
    detail['title'] = title
    detail['abstract'] = abstracts
    return detail

def parse():
    url = 'http://www.kdd.org/kdd2017/accepted-papers'
    res = requests.get(url)
    res.encoding = 'utf-8'  ##設(shè)置編碼
    soup = BeautifulSoup(res.text, 'html.parser')
    papers = soup.select('#fitvid0 , .table-bordered a')
    total_paper = []
    for i in range(len(papers)):
        print(i)
        one_paper = paperDetail(papers[i]['href'])
        total_paper.append(one_paper)

    result = pd.DataFrame(total_paper)
    result = result[['title','author','abstract','link']]
    result.head()
    result.to_csv('paper.csv')
    return result
if __name__ == '__main__':
    parse()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末屉佳,一起剝皮案震驚了整個(gè)濱河市谷朝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌武花,老刑警劉巖圆凰,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異体箕,居然都是意外死亡送朱,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)干旁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)驶沼,“玉大人,你說(shuō)我怎么就攤上這事争群』亓” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵换薄,是天一觀(guān)的道長(zhǎng)玉雾。 經(jīng)常有香客問(wèn)我,道長(zhǎng)轻要,這世上最難降的妖魔是什么复旬? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮冲泥,結(jié)果婚禮上驹碍,老公的妹妹穿的比我還像新娘。我一直安慰自己凡恍,他們只是感情好志秃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著嚼酝,像睡著了一般浮还。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上闽巩,一...
    開(kāi)封第一講書(shū)人閱讀 51,604評(píng)論 1 305
  • 那天钧舌,我揣著相機(jī)與錄音担汤,去河邊找鬼。 笑死洼冻,一個(gè)胖子當(dāng)著我的面吹牛崭歧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碘赖,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼外构!你這毒婦竟也來(lái)了普泡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤审编,失蹤者是張志新(化名)和其女友劉穎撼班,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體垒酬,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砰嘁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了勘究。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矮湘。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖口糕,靈堂內(nèi)的尸體忽然破棺而出缅阳,到底是詐尸還是另有隱情,我是刑警寧澤景描,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布十办,位于F島的核電站,受9級(jí)特大地震影響超棺,放射性物質(zhì)發(fā)生泄漏向族。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一棠绘、第九天 我趴在偏房一處隱蔽的房頂上張望件相。 院中可真熱鬧,春花似錦氧苍、人聲如沸适肠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)侯养。三九已至,卻和暖如春澄干,著一層夾襖步出監(jiān)牢的瞬間逛揩,已是汗流浹背柠傍。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辩稽,地道東北人惧笛。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像逞泄,于是被迫代替她去往敵國(guó)和親患整。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容