python爬蟲教程代碼示例經典例子菜鳥怎麼學

實例3–股票數據定向爬蟲

程序結構如下:

1.先從網站中獲取股票代號列表(requests庫,re庫)

2.遍歷每一隻股票,從股票信息網站中獲得詳細信息

3.使用字典的數據結構,寫入文本文件中

 

更多的內容學習 點我

以下爲代碼:

複製代碼

 1 # 股票數據定向爬蟲
 2 """
 3 Created on Thu Oct 12 16:12:48 2017
 4 
 5 @author: DONG LONG RUI
 6 """
 7 import requests
 8 from bs4 import BeautifulSoup
 9 import re
10 #import traceback
11 
12 def getHTMLText(url,code='utf-8'):#參數code缺省值爲‘utf-8’(編碼方式)
13     try:
14         r=requests.get(url,timeout=30)
15         r.raise_for_status()
16         #r.encoding=r.apparent_encoding
17         r.encoding=code
18         return r.text
19     except:
20         return ''
21     
22 def getStockList(lst,stockURL):
23     html=getHTMLText(stockURL,'GB2312')
24     soup=BeautifulSoup(html,'html.parser')
25     a=soup.find_all('a')
26     for i in a:
27         try:
28             href=i.attrs['href']
29             lst.append(re.findall(r'[s][hz]d{6}',href)[0])
30         except:
31             continue
32     
33 def getStockInfo(lst,stockURL,fpath):
34     count=0#
35     for stock in lst:
36         url=stockURL+stock+'.html'
37         html=getHTMLText(url)
38         try:
39             if html=='':
40                 continue
41             infoDict={}
42             soup=BeautifulSoup(html,'html.parser')
43             stockInfo=soup.find('div',attrs={'class':'stock-bets'})
44             
45             name=stockInfo.find_all(attrs={'class':'bets-name'})[0]
46             infoDict.update({'股票名稱':name.text.split()[0]})#用空格分開,得到股票名稱
47             
48             keyList=stockInfo.find_all('dt')
49             valueList=stockInfo.find_all('dd')
50             for i in range(len(keyList)):
51                 key=keyList[i].text
52                 val=valueList[i].text
53                 infoDict[key]=val
54             
55             with open(fpath,'a',encoding='UTF-8') as f:
56                 f.write(str(infoDict)+'n')
57                 count=count+1#
58                 print('r當前進度:{:.2f}%'.format(count*100/len(lst)),end='')#動態顯示進度,‘r’實現光標移動,即爲不換行的效果
59         except:
60             count=count+1
61             print('r當前進度:{:.2f}%'.format(count*100/len(lst)),end='')#動態顯示進度,‘r’實現光標移動,即爲不換行的效果
62             #traceback.print_exc()
63             continue
64 
65     
66 def main():
67     stock_list_url='http://quote.eastmoney.com/stocklist.html'
68     stock_info_url='https://gupiao.baidu.com/stock/'
69     output_file='C:/Users/DONG LONG RUI/.spyder-py3/BaiduStockInfo.txt'
70     slist=[]
71     getStockList(slist,stock_list_url)
72     getStockInfo(slist,stock_info_url,output_file)
73     
74 main()

複製代碼

由於requests庫爬蟲的限制,我運行後速度會比較慢,後續可嘗試scrapy爬蟲。

 

又想到bs4中的BeautifulSoup和re庫都可用於搜索html中的目標信息,但兩者一般結合起來使用:

先用BeautifulSoup找到目標信息所在的特定標籤,然後在這些標籤內容中使用正則表達式去匹配。

寫作背景:作爲一名金融從業者,在個人的業務投資上,經常會需要通過數據分析,加上金融邏輯的推演決定自己的投資策略。提到數據分析,就必然會提到數據採集。作爲個人投資者,數據信息最多的就是來自互聯網。如何高效獲取自己需要的數據並加以分析,就是在下開始學習爬蟲的原因。通過記錄學習情況,梳理自己的知識框架,同時也能分享給大家,找到一起努力奮鬥的小夥伴。

個人背景:理工科類大學畢業,從事銀行、保險等金融相關工作近10年。

編程能力:大學期間學過C語言和SQL語言,但是10年來幾乎很少應用,忘得差不多。

學習Python的原因:網上關於Python的爬蟲案例較多,據說Python語言相比C和JAVA更近自然語言。

學習時長:工作之後的業餘時間,累計近一個月。

學習成果:掌握簡單的爬蟲技術。

系統環境:windows 10

IDE:Pycharm

Python版本:Python2.7 (Ananconda)

知識點:1、涉及到的庫urllib,urllib2,re,beautifulsoup,lxml,gzip,StringIO,csv,mysql

2、掌握用urllib,urllib2獲取網頁

1)最簡單的獲取方式urllib2.urlopen()

2)加入報頭headers

3)加入代理proxy

4)加入cookies

5)定製自己的opener

6)網頁亂碼的處理:chardet、decode()、gzip、StringIO庫

3、通過網頁解析,獲得需要的數據

1)學會用正則表達式解析

2)學會用BeautifulSoup解析網頁

3)學會用lxml xpath解析網頁

4、數據的讀寫

1)txt文件的讀寫

2)CSV文件的讀寫

3)MySQL的讀寫

更多的內容學習 點我

本文適用人羣:零基礎學爬蟲、小白學爬蟲、簡單爬蟲的學習框架

其他:1)本文通過爬蟲案例學習以上學習以上知識點。並儘可能對每一段代碼做註解,

註解開頭爲#。

2)本文不會涉及到class類和函數的概念,便於初學者學習基本知識。

3)本文僅作爲知識學習的筆記與分享,請勿在未經作者的同意下商用,更希望每一個編程愛好者以陽光的心態學習,不要用於違法亂紀。

參考網站:1)廖雪峯的Python 2.7教程:學習所有Python的最基礎語法,當詞典用。

2)簡明 Python 教程,當詞典用

3)崔慶才的個人博客,Python爬蟲學習系列教程 | 靜覓,相當多的實例教程,唯一 缺點就是很多文章是半年前到1年前寫的,很多網頁都紛紛改版,直接運行裏 面的代碼無法爬取,但是可以作爲爬蟲思路的指引。

爬取對象:上海房產網_上海二手房_上海新房_上海租房-上海鏈家網

感謝鏈家網,提供了很好的學習土壤。

我是分割線————————————————————————————————————

正文與代碼:

# encoding: utf-8

#該行註釋是爲了解決python中文的亂碼問題,所有中文以utf-8格式解析,也可以寫成 # -*- coding: utf-8 -*-

1、添加需要用到的庫urllib,urllib2,re,beautifulsoup,lxml,csv,mysql,gzip,StringIO

import urllib #網頁解析庫
import urllib2 #網頁解析庫
import re  # 正則表達式的庫
import cookielib  #cookie的庫
from bs4 import BeautifulSoup  # BeautifulSoup的庫
import lxml.html  # lxml xpath的庫
from lxml import etree # lxml xpath的庫
import csv #csv的庫
from mysql import connector  # 連接MySQL的庫

庫的安裝命令,cmd下執行:pip install urllib
pip install urllib==1.0.0 #制定版本的庫安裝
pip install –upgrade urllib #庫的升級
其他pip命令可以參考:pip安裝使用詳解 – 愛開源

2、掌握用urllib,urllib2獲取網頁

1)最簡單的形式:

url = 'http://sh.lianjia.com/ershoufang/d1'
response = urllib2.urlopen(url)
content = response.read()
print content

輸出結果:

說明爬取成功,看來鏈家非常的友好,並沒有設立針對urlopen顯性的反爬蟲機制。

怎麼判斷爬取是否成功

print content.getcode()

如果返回值是200則爬取成功,如果是301、302則是重定位,如果是404則是表示頁面不存在
詳細可以參考 301、404、200、304等HTTP狀態 – Lynn.Zhou的專欄 – 博客頻道 – CSDN.NET

2)加入報頭headers,如果遇到有顯性反爬蟲機制的情況,返回一般就不是200了,這個時候怎麼辦?就給爬蟲帶個帽子,假裝自己不是爬蟲。

headers = {
    'User - Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
}

報頭一般用瀏覽器按F12,查看Network選項卡里都能看到,實在不行,你可以把整個Request Headers裏的內容,以字典的方式扔進去。

3)嘗試加入代理IP機制,現在越來越多的網站 沒有顯性的反爬蟲模式,而是採用隱性的反爬蟲機制,比如你開始爬取第一頁的時候沒問題,但是爬着爬着就把你BAN了,而一般BAN的是你的IP地址,所以在做大量數據爬取的時候建議加入IP代理機制。

代理IP地址怎麼獲取,請自行百度或者谷歌。

proxy_handler = urllib2.ProxyHandler({"http": '101.231.67.202:808'})
opener = urllib2.build_opener(proxy_handler,urllib2.HTTPHandler)

4)加入cookies

cookie = cookielib.LWPCookieJar()
cookie_handler = urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(cookie_handler,urllib2.HTTPHandler)

5)定製自己的opener

#同時加入proxy和cookie
opener = urllib2.build_opener(proxy_handler,cookie_handler,urllib2.HTTPHandler)

6)網頁亂碼的處理:chardet、decode()、gzip、StringIO 亂碼錶現一:chardet、decode()

有時解析網頁會發現大量的奇怪符號,嗯,這就是亂碼。亂碼的一般都是中文。
訪問的網站是搜狐,同樣調取查看器。

在<head>裏有以下內容:
<meta http-equiv=”content-type” content=”text/html; charset=GBK”>
說明網站的中文是用GBK的。

print content.read().decode('gbk')

decode的其他形式:decode(‘utf-8′,’ignore’) #忽略不能解碼的內容,確保命令正常運行

用chardet的庫來解析網絡的代碼

import chardet
url = 'http://www.sohu.com'
response = urllib2.urlopen(url)
content = response.read()
charset_info = chardet.detect(content)
print charset_info

亂碼錶現二:調用gzip、StringIO庫

所有的內容都亂碼了。。。。
<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
明明是gb2312,用decode(‘gbk’,’ignore’)居然不能解碼。。。
亂碼的網頁報頭

普通網頁的報頭

關鍵在於RESPONSE裏是否有 Vary:Accept-Encoding。如果沒有申明,網頁要自行解壓。
gzip和StringIO派上用處了:

import gzip
import StringIO
url = 'http://land.fang.com'
response = urllib2.urlopen(url)
content = response.read()
content = StringIO.StringIO(content)
gzipper = gzip.GzipFile(fileobj=content)
content = gzipper.read().decode('gbk')

3、通過網頁解析,獲得需要的數據
還是以上海二手房|上海二手房出售|最新上海二手房信息 – 上海鏈家網爲案例

獲取所有行政區的鏈接和名字
1)學會用正則表達式解析

pattern_district = re.compile('<a href="/ershoufang.*?class="" >(.*?)</a>', re.S)
districts = re.findall(pattern_district, content)
for district in districts:
     print district

熟練掌握.*?和(.*?)的貪婪匹配技巧,一般都能輕鬆獲取
但是如果要獲取行政區的鏈接就很痛苦了,因爲正則表達式只能找規律,周圍匹配的字段越特殊,那麼越容易找到。

pattern_district = re.compile('<a href="(.*?)" gahref=".*? class="" >(.*?)</a>', re.S) 
districts = re.findall(pattern_district, content)
for district in districts: 
print district 

這樣寫的結果,會匹配到很多不想管的內容

打包一起找再處理

pattern_district = re.compile('<a href="/ershoufang/".*?</a>.*?<div class="item-list">(.*?)</div>',re.S)
districts = re.findall(pattern_district, content)
districts =districts[0]
print districts

再一次正則匹配:

pattern = re.compile('<a href="(.*?)" gahref.*?>(.*?)</a>',re.S)
item = re.findall(pattern,districts)
for i in item:
    print i[0], i[1]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章