欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python 爬蟲學習筆記之多線程爬蟲

 更新時間:2016年09月21日 10:03:24   作者:千里追風  
本文給大家介紹的是python基于XPath實現(xiàn)多線程爬蟲的實例以及XPath的介紹安裝和簡單用法,非常的細致,有需要的小伙伴可以參考下

XPath 的安裝以及使用

1 . XPath 的介紹

剛學過正則表達式,用的正順手,現(xiàn)在就把正則表達式替換掉,使用 XPath,有人表示這太坑爹了,早知道剛上來就學習 XPath 多省事 啊。其實我個人認為學習一下正則表達式是大有益處的,之所以換成 XPath ,我個人認為是因為它定位更準確,使用更加便捷??赡苡械娜藢?XPath 和正則表達式的區(qū)別不太清楚,舉個例子來說吧,用正則表達式提取我們的內容,就好比說一個人想去天安門,地址的描述是左邊有一個圓形建筑,右邊是一個方形建筑,你去找吧,而使用 XPath 的話,地址的描述就變成了天安門的具體地址。怎么樣?相比之下,哪種方式效率更高,找的更準確呢?

2 . XPath 的安裝

XPath 包含在 lxml 庫中,那么我們到哪里去下載呢? 點擊此處 ,進入網頁后按住 ctrl+f 搜索 lxml ,然后進行下載,下載完畢之后將文件拓展名改為 .zip ,然后進行解壓,將名為 lxml 的文件夾復制粘貼到 Python 的 Lib 目錄下,這樣就安裝完畢了。

3 . XPath 的使用

為了方便演示,我利用 Html 寫了個簡單的網頁,代碼如下所示(為了節(jié)省時間,方便小伙伴們直接進行測試,可直接復制粘貼我的代碼)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Test Html</title>
</head>
<body>
<div id="content">
  <ul id="like">
    <li>like one</li>
    <li>like two</li>
    <li>like three</li>
  </ul>

  <ul id="hate">
    <li>hate one</li>
    <li>hate two</li>
    <li>hate three</li>
  </ul>

  <div id="url">
    <a >百度一下</a>
    <a >好123</a>
  </div>
</div>

</body></html>

用谷歌瀏覽器打開這個網頁,然后右擊,選擇檢查,會出現(xiàn)如下所示界面

這個時候你鼠標右擊任何一行 html 代碼,都可以看到一個 Copy,將鼠標放上去,就可以看到 Copy XPath ,先復制下來,怎么用呢?

# coding=utf-8
from lxml import etree

f = open('myHtml.html','r')
html = f.read()
f.close()

selector = etree.HTML(html)
content = selector.xpath('//*[@id="like"]/li/text()')
for each in content:
  print each

看看打印結果

like one
like two
like three

很顯然,將我們想要的內容打印下來了,注意我們在 xpath() 中使用了 text() 函數,這個函數就是獲取其中的內容,但是如果我們想獲取一個屬性,該怎么辦?比如說我們想得到 html 中的兩個鏈接地址,也就是 href 屬性,我們可以這么操作

content = selector.xpath('//*[@id="url"]/a/@href')
for each in content:
  print each

這個時候的打印結果就是

http://www.baidu.com
http://www.hao123.com

看到現(xiàn)在大家大概也就對 xpath() 中的符號有了一定的了解,比如一開始的 // 指的就是根目錄,而 / 就是父節(jié)點下的子節(jié)點,其他的 id 屬性也是一步一步從上往下尋找的,由于這是一種樹結構,所以也難怪方法的名字為 etree()。

4 . XPath 的特殊用法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="likeone">like one</div>
<div id="liketwo">like two</div>
<div id="likethree">like three</div>

</body>
</html>

面對上面的一個網頁,我們應該如何獲取到三行的內容的 ? 嗯哼,很簡單,我寫三個 XPath 語句不就好了,so easy 。 如果真是這樣,那么我們的效率好像是太低了一點,仔細看看這三行 div 的 id 屬性,好像前四個字母都是 like, 那就好辦了,我們可以使用 starts-with 對這三行進行同時提取,如下所示

content = selector.xpath('//div[starts-with(@id,"like")]/text()')

不過這樣有一點麻煩的地方,我們就需要手動的去寫 XPath 路徑了,當然也可以復制粘貼下來在進行修改,這就是提升復雜度來換取效率的問題了。再來看看標簽嵌套標簽的提取情況

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="content">
  <div id="text">
    <p>hello
      <b> world
        <font color="#ffe4c4">
          Python
        </font>
      </b>
    </p>
  </div>
</div>

</body>
</html>

像上面這樣的一個網頁,如果我們想獲取到  hello world Python 語句,該怎么獲取呢?很明顯這是一種標簽嵌套標簽的情況,我們按照正常情況進行提取,看看結果如何

content = selector.xpath('//*[@id="text"]/p/text()')
for each in content:
  print each

運行之后,很遺憾的,只打印出了 hello 字樣,其他字符丟失了,該怎么辦呢?這種情況可以借助于 string(.)如下所示

content = selector.xpath('//*[@id="text"]/p')[0]
info = content.xpath('string(.)')
data = info.replace('\n','').replace(' ','')
print data

這樣就可以打印出正確內容了,至于第三行為什么存在,你可以將其去掉看看結果,到時候你自然就明白了。

Python 并行化的簡單介紹

有人說 Python 中的并行化并不是真正的并行化,但是多線程還是能夠顯著提高我們代碼的執(zhí)行效率,為我們節(jié)省下來一大筆時間,下面我們就針對單線程和多線程進行時間上的比較。

# coding=utf-8
import requests
from multiprocessing.dummy import Pool as ThreadPool
import time


def getsource(url):
  html = requests.get(url)

if __name__ == '__main__':
  urls = []
  for i in range(50, 500, 50):
    newpage = 'http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=' + str(i)
    urls.append(newpage)

  # 單線程計時
  time1 = time.time()
  for i in urls:
    print i
    getsource(i)
  time2 = time.time()

  print '單線程耗時 : ' + str(time2 - time1) + ' s'

  # 多線程計時
  pool = ThreadPool(4)
  time3 = time.time()
  results = pool.map(getsource, urls)
  pool.close()
  pool.join()
  time4 = time.time()
  print '多線程耗時 : ' + str(time4 - time3) + ' s'

打印結果為

http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=50
http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=100
http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=150
http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=200
http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=250
http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=300
http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=350
http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=400
http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=450
單線程耗時 : 7.26399993896 s
多線程耗時 : 2.49799990654 s

至于以上鏈接為什么設置間隔為 50,是因為我發(fā)現(xiàn)在百度貼吧上沒翻一頁,pn 的值就會增加 50。 通過以上結果我們發(fā)現(xiàn),多線程相比于單線程效率提升了太多太多。至于以上代碼中多線程的使用,我就不再過多講解,我相信只要接觸過 Java 的人對多線程的使用不會陌生,其實都是大差不差。沒有接觸過 Java ?那就對不起了,以上代碼請自行消化吧。

實戰(zhàn) -- 爬取當當網書籍信息

一直以來都在當當網購買書籍,既然學會了如何利用 Python 爬取信息,那么首先就來爬取一下當當網中的書籍信息吧。本實戰(zhàn)完成之后的內容如下所示

在當當網中搜索 Java ,出現(xiàn)了89頁內容,我選擇爬取了前 80 頁,而且為了比較多線程和單線程的效率,我特意在這里對二者進行了比較,其中單線程爬取所用時間為 67s,而多線程僅為 15s 。

如何爬取網頁,在上面 XPath 的使用中我們也已經做了介紹,無非就是進入網頁,右擊選擇檢查,查看網頁 html 代碼,然后尋找規(guī)律,進行信息的提取,在這里就不在多介紹,由于代碼比較短,所以在這里直接上源代碼。

# coding=utf8
import requests
import re
import time
from lxml import etree
from multiprocessing.dummy import Pool as ThreadPool
import sys

reload(sys)
sys.setdefaultencoding('utf-8')

def changepage(url, total):
  urls = []
  nowpage = int(re.search('(\d+)', url, re.S).group(1))
  for i in range(nowpage, total + 1):
    link = re.sub('page_index=(\d+)', 'page_index=%s' % i, url, re.S)
    urls.append(link)
  return urls

def spider(url):
  html = requests.get(url)
  content = html.text

  selector = etree.HTML(content)
  title = []
  title = selector.xpath('//*[@id="component_0__0__6612"]/li/a/@title')

  detail = []
  detail = selector.xpath('//*[@id="component_0__0__6612"]/li/p[3]/span[1]/text()')
  saveinfo(title,detail)

def saveinfo(title, detail):
  length1 = len(title)
  for i in range(0, length1 - 1):
    f.writelines(title[i] + '\n')
    f.writelines(detail[i] + '\n\n')

if __name__ == '__main__':
  pool = ThreadPool(4)
  f = open('info.txt', 'a')
  url = 'http://search.dangdang.com/?key=Java&act=input&page_index=1'
  urls = changepage(url, 80)

  time1 = time.time()
  pool.map(spider, urls)
  pool.close()
  pool.join()

  f.close()
  print '爬取成功!'
  time2 = time.time()
  print '多線程耗時 : ' + str(time2 - time1) + 's'

  # time1 = time.time()
  # for each in urls:
  #   spider(each)
  # time2 = time.time()
  # f.close()

  # print '單線程耗時 : ' + str(time2 - time1) + 's'

可見,以上代碼中的知識,我們都在介紹 XPath 和 并行化 中做了詳細的介紹,所以閱讀起來十分輕松。

好了,到今天為止,Python 爬蟲相關系列的文章到此結束,謝謝你的觀看。

相關文章

  • pycharm 關掉syntax檢查操作

    pycharm 關掉syntax檢查操作

    這篇文章主要介紹了pycharm 關掉syntax檢查操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • scrapy與selenium結合爬取數據(爬取動態(tài)網站)的示例代碼

    scrapy與selenium結合爬取數據(爬取動態(tài)網站)的示例代碼

    這篇文章主要介紹了scrapy與selenium結合爬取數據的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • python實現(xiàn)簡易聊天室(Linux終端)

    python實現(xiàn)簡易聊天室(Linux終端)

    這篇文章主要為大家詳細介紹了Linux終端上python實現(xiàn)簡易聊天室功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 在Python中操作字典之clear()方法的使用

    在Python中操作字典之clear()方法的使用

    這篇文章主要介紹了在Python中操作字典之clear()方法的使用,是Python入門的基礎知識,需要的朋友可以參考下
    2015-05-05
  • 局域網內python socket實現(xiàn)windows與linux間的消息傳送

    局域網內python socket實現(xiàn)windows與linux間的消息傳送

    這篇文章主要介紹了局域網內python socket實現(xiàn)windows與linux間的消息傳送的相關知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • python機器學習之神經網絡

    python機器學習之神經網絡

    這篇文章主要介紹了python機器學習之神經網絡,文中有非常詳細的代碼示例,對正在學習python的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-04-04
  • numpy中l(wèi)oadtxt 的用法詳解

    numpy中l(wèi)oadtxt 的用法詳解

    這篇文章主要介紹了numpy中l(wèi)oadtxt 的用法詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • Python logging自定義字段輸出及打印顏色

    Python logging自定義字段輸出及打印顏色

    這篇文章主要介紹了Python logging自定義字段輸出及打印顏色,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • Django使用模板后無法找到靜態(tài)資源文件問題解決

    Django使用模板后無法找到靜態(tài)資源文件問題解決

    這篇文章主要介紹了Django使用模板后無法找到靜態(tài)資源文件問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • python安裝pil庫方法及代碼

    python安裝pil庫方法及代碼

    在本篇內容里我們給大家分享的是關于python安裝pil庫方法及代碼內容,有此需要的朋友們可以參考下。
    2019-06-06

最新評論