天羅地網——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文件夾下。網絡

經過Requests獲取網頁源代碼

無反爬蟲機制

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

import requests

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

print(html.text)

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

有反爬蟲機制

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

<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</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('<a target="_blank" href="(.*?)"', html.text, re.S)

for each in href:
    print each

向網頁提交數據

Get與Post

他們的區別以下所示:
- Get是從服務器上獲取數據
- Post是向服務器傳送數據
- Get經過構造url中的參數來實現功能
- Post將數據放在header提交數據

網頁分析工具

Chrome調試功能——Network調試

在Network中找到Post提交的地方,找到Form Data,這就是表單數據。

構造表單

Post方式提交表單。

import requests
import re

url = 'https://www.crowdfunder.com/browse/deals&template=false'

data = {
    'entities_only':'true',
    'page':'2'
}
html_post = requests.post(url,data=data)
title = re.findall('"card-title">(.*?)</div>',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-8
import requests
from 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">須要的內容1</div>
  <div id="test-2">須要的內容2</div>
  <div id="test-3">須要的內容3</div>

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

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

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

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

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

嵌套標籤

例如:

<div id=「class」>text1
    <font color=red>text2</font>
    text3
</div>

相似這種嵌套標籤的,若是咱們使用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。

·
相關文章
相關標籤/搜索