天羅地網——Python爬蟲初初初探

環境準備

Python

咱們使用Python2.7進行開發,注意配置好環境變量。html

IDE

咱們使用Pycharm進行開發,它和大名鼎鼎的Android Studio、IDEA同出一門——Jet Brains。python

關於破解,很無恥的貼兩個:android

用戶名:yueting3527
註冊碼:===== LICENSE BEGIN =====93347-12042010
00001FMHemWIs"6wozMZnat3IgXKXJ
2!nV2I6kSO48hgGLa9JNgjQ5oKz1Us
FFR8k"nGzJHzjQT6IBG!1fbQZn9!Vi===== LICENSE END =====

用戶名:yueting3527

註冊碼:===== LICENSE BEGIN =====93347-12042010
00001FMHemWIs"6wozMZnat3IgXKXJ
2!nV2I6kSO48hgGLa9JNgjQ5oKz1Us
FFR8k"nGzJHzjQT6IBG!1fbQZn9!Vi===== LICENSE END =====

Requests模塊

Requests模塊是一個用於替代Python URLLib2的一個第三方網絡請求庫。nginx

安裝

  • Windows:pip install requests
  • Linux & Mac:sudo pip install requests

但因爲有些比較奇怪的緣由,致使這個下載過程異常艱辛,因此咱們常常須要使用這樣一個網站來幫助咱們下載:web

http://www.lfd.uci.edu/~gohlke/pythonlibs/正則表達式

這裏面鏡像收集了幾乎全部的Python第三方庫,咱們搜索Requests,點擊下載。網絡

下載完畢後,更改後綴名爲zip。並將解壓出的Requests文件夾放到Python的Lib文件夾下。eclipse

經過Requests獲取網頁源代碼

無反爬蟲機制

直接使用Requests庫的get方法獲取網頁源代碼:ide

import requests

html = requests.get('http://www.hujiang.com/')

print(html.text)

在終端中,咱們就能夠看見生成的網頁源代碼了。post

有反爬蟲機制

可是,不少網站並不會輕鬆的讓爬蟲獲取到網頁信息,這時候,咱們就須要經過修改Http頭信息的方式來獲取。

例如咱們使用一樣的代碼去爬個人博客 http://blog.csdn.net/eclipsexys 在終端中,咱們能夠看見這樣一段話:

<html><head><title>403 Forbiddentitle>head><body bgcolor="white"><center><h1>403 Forbiddenh1>center><hr><center>nginxcenter>body>html>

403,這時候,咱們就須要修改下爬蟲代碼。

首先,咱們在頁面上點擊右鍵選擇審查元素,找到Network,刷新下, 選擇任意一個元素,找到最後的User—Agent:

這裏寫圖片描述

User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36

這就是咱們的Http請求頭。如今咱們修改代碼:

import requests

head = {    'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'}

html = requests.get('http://blog.csdn.net/eclipsexys', headers = head)

print(html.text.encode('utf-8'))

添加請求頭,並設置下編碼格式爲UTF-8。(Windows下默認爲GBK,請先修改coding爲UTF-8)

ps: 在Python文件中,若是咱們要輸入中文,須要指定下文件的字符集:

# coding=utf-8
具體見 https://www.python.org/dev/peps/pep-0263/

咱們再運行,如今就能夠正常獲取源代碼了。

Requests正則搜索

直接get出來的內容,都是網頁的全部源代碼,這確定不是咱們須要的,因此,咱們能夠經過正則表達式來提取咱們所須要的內容。
例如,咱們想提取網頁中的全部超連接,OK,咱們來看如何實現:

re模塊

首先咱們須要引入re模塊,re模塊是正則表達式的模塊,使用與web端的正則同樣:

import requests
import re

head = {    'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'}

html = requests.get('http://www.hujiang.com/', headers=head)
html.encoding = "utf-8"href = re.findall('(.*?)

',html_post.text,re.S)for each in title:    print each

XPath

XPath,就是XML路徑語言,咱們在尋找一個元素時,若是使用正則表達式,能夠這麼說,我要找一個長頭髮、180cm的女人。那麼若是要用XPath來表達,就是XX公司XX部門的前臺。

lxml

在Python中使用XPath,咱們須要使用第三方模塊lxml,安裝如同Requests。

獲取HTML的XPath路徑

打開Chrome的審覈元素,咱們找到任何一個元素,點擊右鍵,選擇copy XPath便可。
固然,咱們也能夠手寫,它的基本語法以下:

  • //定位根節點
  • /往下層尋找
  • 提取文本內容:/text()
  • 提取屬性內容: /@xxxx

好比咱們選擇這個地址:http://www.imooc.com/course/list?c=android&page=2

打開審覈元素:

這裏寫圖片描述

這樣咱們就很是方便的得到了元素的XPath,同時,咱們也能夠根據規則來手動修改。

爬取內容

使用XPath基本是以下三個步驟:

  • from lxml import etree
  • Selector = etree.HTML(HTML Source)
  • Selector.xpath(XPath)

咱們一樣之前面的網址爲例,咱們抓取所選的那門課程的標題:

# coding=utf-8import requestsfrom lxml import etree

html = requests.get("http://www.imooc.com/course/list?c=android&page=2")
html.encoding = 'utf-8'selector = etree.HTML(html.text)

content = selector.xpath('//*[@id="main"]/div/div/div[3]/div[1]/ul/li[1]/a/h5/span/text()')for each in content:
    print each

這樣咱們就獲取了對應的內容, 搜索方法,其實跟咱們經過地址來定位是同樣的,中國-上海-浦東新區(內容惟一時,前面可跳過)-張江高科-滬江網-徐宜生

那麼若是咱們須要爬取全部的課程信息要怎麼辦呢?咱們能夠看見生成的XPath中,有一個li[1],它對應的是咱們源代碼中的那個列表,咱們選擇1是由於選擇具體的一項,若是咱們去掉這個1,返回的就是一個列表,就是咱們要的全部元素,這裏就不詳細演示了。

XPath高級使用技巧

相同字符串開頭、但屬性不一樣

例如:

  <div id="test-1">須要的內容1div>
  <div id="test-2">須要的內容2div>
  <div id="test-3">須要的內容3div>

咱們須要提早全部內容,可是他們的屬性都不一樣,咱們先看下一個元素的XPath:

//*[@id="test-1"]/text()

可見,ID決定了元素,因此要取出這樣的元素時,咱們須要使用XPath的starts-with(@屬性名稱, 屬性字符相同部分)方法:

//*[starts-with(@id,"test")]/text()

只須要將[]中的內容使用starts-with方法進行匹配就OK了。

嵌套標籤

例如:

<div id=「class」>text1    <font color=red>text2font>
    text3div>

相似這種嵌套標籤的,若是咱們使用XPath獲取第一級的text,那麼只能獲取text1和text3,若是要獲取text2,咱們就須要使用string(.)方法。

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

經過string(.),咱們能夠獲取嵌套標籤的text,至關於遍歷子標籤,獲取text。

最後

寫本篇博客的目的在於後面要進行的一次抽獎活動,你們都知道,個人新書《Android羣英傳》已經正式上市了,爲了報答各位的大力推薦,我準備在CSDN博客準備一次抽獎,這篇博客所講的,天然是抽獎所須要的預備知識,歡迎你們預熱~~~

相關文章
相關標籤/搜索