爬蟲學習筆記

爬蟲學習筆記

list

  1. extend函數 將兩個list連起來

  2. 整齊打印抓到的html頁面:直接print re.text就行

  3. str 替換函數,replace,替換字符串內容

  4. list index()求 元素的下標

  5. 字符串中加數字: sd=’%s_%s’%(i,t)
    . for (i1, i2) in zip(list1,list2): 同時遍歷兩個list

  6. .找class span中的內容 self.title.append(lable.split(“\”“)[1])

  7. str.isalpha()判斷是否是字母

  8. str.isdigit()判斷是否是數字 判斷是否包含字母或者數字:re.search(‘[a-z]’,str)

  9. jieba分詞:

    txt = open("bxj.txt", "r", encoding='utf-8').read()
           words = jieba.lcut(txt)  # words全部截取
           counts = {}
           for word in words:
               if len(word) == 1:
                   continue
               else:
                   counts[word] = counts.get(word, 0) + 1
           sd=sorted(counts.items(),key=lambda asd:asd[1],reverse=True)
  10. tuple 強制轉換轉list
    sd=list(sd)

解析數據

Beautifulsoup

初始化

soup = BeautifulSoup(html, ‘html.parser’)

深層次查找標籤

bs4可以通過find 或者find_all()返回後再次調用,find或者find_all()

然後,通過result[‘href’]得到href的標籤

tag

有兩個屬性: name,attrs

  1. 找出所有鏈接
    names=soup.find_all(‘a’,{‘class’:’headpic’})
    for each in names:
    # print(each)
    href=each[‘href’]
    print(href)

  2. bs4 find_all(‘td’)找出所有,其他也一樣

  3. 找出 sd=message.find_all(‘td’,{“class”:”tWhite”})

  4. 提取信息 只有一條的情況下: sd[0].getText

  5. a=each.find(‘a’) print(a.text)得到a 中間text的文件內容

  6. a=each.find(‘a’) print(a[href])找到a標籤中的href

  7. tr=soup.find(attrs{‘id’:’places_area_row’}) 找出id 屬性值爲‘’ 的數據

  8. bs 對象分爲4大類 Tag NavigableString BeautifulSoup Comment
    tag:有兩個屬性: attrs name name 打印出來 標籤的類別 比如 span
    tag.attrs: {‘class’: [‘f666’]}找出span中的屬性
    tag.text打印出標籤內部的內容

  9. 找到< li >中的文字,用.string方法

lxml

導入方式

import lxml.html//
  1. tree=lxml.html.fromstring(html)

    . td=tree.cssselect(‘tr# places_area__row > td.w2p_fw’)[0]
    代表id,首先找到tr爲places_area的元素,然後找到td類屬性爲w2p_fw的元素

  2. 然後text_content得到內容

  3. 選擇a內span 標籤 : a span

  4. title 屬性爲 home 的所有標籤 a[title=home]

  5. 選擇class=link 的所有f a.link
獲得div標籤下的所有class

div_class=tree.xpath(‘//div/@class’)
print(div_class)

xpath學習

page = etree.HTML(html.lower().decode(‘utf-8’))

定位html標籤,相對路徑,絕對路徑

  • 絕對
    path.xpath(u”/html/body/p”)
  • 相對
    path.xpath(“//p”) 找出所有的p標籤

定位到“

World News only on this page


p = page.xpath(u”/html/body/p[@style=’font-size: 200%’]”)
用如@name, @id, @value, @href, @src, @class….

函數text 取出p中的文本
position 是節點的位置 li[position()=2]”表示取得第二個li節點

代表所有的節點,比如用”/html/body//span可以取出body下第二級的所有span,而不管它上一級是div還是p或是其它什麼東東。

href 找出所有的a標籤和內容

hrefs=page.xpath(u”//a”)
for href in hrefs:
print(href.attrib)
print(href.text)’
找出鏈接
print(href.get(‘href’))

position

hrefs=page.xpath(u”//a[position()=2]”)
找出所有href標籤中的第二個

取不到的內容

用tail 屬性

print (u.tail)
結束節點後面的內容

解析字符串

處理url

  1. urljoin from urlparse import url

urls.append(urljoin(“https://tieba.baidu.com/“,each.get(‘href’)))

返回response的url: response.geturl()
  1. str 的操作:info=”.join(info.split()) 去掉所有的空格和換行符
  2. 不換行輸出 print(‘123123’, end=”)

  3. plt.rcParams[‘font.sans-serif’] = [‘SimHei’] 解決中文亂
    碼問題

  4. dic.get(‘fan’)==None dic[‘fan’]=1 dic檢查元素是否存在 以及添加元素的方法

解析json

json.loads()

  1. 將json結構的str 轉換爲 python類型數據結構 dict類型

json.dumps()

  1. 將python 的數據結構 dict 轉換爲json結構的str

抓取知乎內容

抓取我的收藏:

li class=” “> a class=” “> 2

urlib 和urllib2學習

標準款

response=urllib2.open(‘http://python.org/‘)
html=response.read()

加上header 和數據

user_agent='Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Mobile Safari/537.36'

headers={'User-Agent':user_agent}

values={‘name’ : ‘Michael Foord’, ‘location’ : ‘Northampton’, ‘language’ : ‘Python’ }
headers={‘user_agent’:user_agent)
data=urllib.urlencode(values)
req=urllib2.request(‘http://python.org‘,data,headers)
response=urllib2.urlopen(req,)
html=response.read()

加上代理

proxy_handler=urllib2.ProxyHandler({“http”:”http://114.215.95.188:3128“})

opener=urllib2.build_opener(proxy_handler)

urllib2.install_opener(opener)

加上cookie

  1. 設置cookie cookie=cookielib.CookieJar()
  2. build一個opener opener=urlliib2.build_opener(urllib.HTTPCookieProcessor(cj))
  3. 使用opener打開構建的request請求

內容保存到本地

將html 寫入txt

html=req.text
with open('zhihu_html.text','w') as opener:
    opener.write(html)
    dest_dir爲本地地址

urllib.urlretrieve(url , dest_dir)

將url存在本地磁盤的方法

  1. 將抓取下來的網頁按照域名保存爲一個個文件夾,然後將域名後面的東西保存爲文件地址

解決亂碼

如果原始是GBK
html=unicode(html,’GBK’).encode(‘UTF-8’)

判斷遍歷的最大深度

最原始的網頁深度爲 1:
如果 抓取到的網頁來自原始網頁 被抓取的網頁深度+1

如果一個url的深度大於最大深度 就不把他加在隊列中
慢慢的 隊列就空了,抓取停止了

也就是說 設置最大深度爲4

最多再抓取三層的信息


項目總結 2018.4.19

算是第一個爬蟲小項目: 先總結一下

  • 開始:通過crawler 方法,傳入基本信息

  • 維護一個url隊列
    從最初的url抓取到的url 如果抓取過,就 添加在對列中, deepth+=1

  • 如果url在本地磁盤緩存中,html就從本地緩存中調用
    否則進行下載,並且將下載的頁面寫入緩存

    • 解析:通過正則解析html 找到需要的url
      一個html頁面所有的url抓取完畢, 該html對應的url出隊列
  • 定時,在下載時,爲了防止ip被封,寫一個定時類,可以在每次下載時延緩一定的時間

  • 當隊列爲空,所有的抓取完畢時,調用回調函數,將信息寫在csv文件中(這是個缺點,如果網絡中斷,豈不是之前的信息都要gg)

  • 在抓取完一個url後,將html 文件寫入本地緩存

文件功能:

playground.py:程序的入口
Downloader.py:下載方法的實現
disk_cache.py:頁面緩存的實現

待完善:

  1. 用芒果db來代替本地儲存
  2. 對爬蟲功能的增加,比如識破驗證碼,處理ajax請求
  3. csv文件那塊還要再商議一下
  4. 如果能用代理的話,也不錯
  5. 分佈式定時任務框架rabbitMq 和celery學一下

Mongo DB的使用

概念

集合:

mogod -dbpath 是儲存文檔的地方,相當於mysql的表格
集合沒有固定的結構,比較鬆散,但集合中的文檔,一般都有相關性

當插入一個文檔時,集合就會建立

document

爲主鍵 |

SQL術語/概念 MongoDB術語/概念 解釋/說明
database database 數據庫
table collection 數據庫表/集合
row document 數據記錄行/文檔
column field 數據字段/域
index index 索引
table joins 表連接,MongoDB不支持
primary key primary key 主鍵,MongoDB自動將_id字段設置

數據類型

ObjectId 類似唯一的主鍵

運行mongoDB

mongod

常用shell

show dbs
use db

dbname.system.* //查看數據庫的所有信息

insert
WriteResult({ “nInserted” : 1 })

刪除當前數據庫
db.dropDatabase()

創建集合

db.createCollection(“runoob”)

顯示所有集合

show collections

插入文檔

以下文檔可以存儲在 MongoDB 的 runoob 數據庫 的 col 集合中:

db.COLLECTION_NAME.insert(document)

db.col.insert({title: ‘MongoDB 教程’, description: ‘MongoDB 是一個 Nosql 數據庫’, by: ‘菜鳥教程’, url: ‘http://www.runoob.com‘, tags: [‘mongodb’, ‘database’, ‘NoSQL’], likes: 100 })
終端連接服務器進入shell :mongo

查看集合中的文檔

db.col.find()
db.collections.count() 查看錶中的元素個數

python連接mongodb 放在local中

  1. 默認端口號27017
    2.終端輸入 mongo 進入sql命令行

mysql 爲key-value 模式

mongodb 的配置文件
/usr/local/etc

文件默認路徑:/usr/local/var/mongodb

修改了數據庫路徑

賦權: sudo chown id -u /Users/fanjialiang2401/data/mongo/

查看mongodb 是否在運行

mongodb 正確退出方式:
mongo // 從linux命令行進入mongod命令行

use admin // 切換到管理員模式

db.shutdownServer() // 關閉mongodb服務

pymongo

shell

  1. show dbs
  2. use db
  3. db.webpage.find()找出collection爲webpage的所有元素
  4. db.webpage.count()
    . db.webpage.find()
  5. 搜索所有的值
for item in table.find():
    print(item)
  1. db.collection.createIndex( { name: -1 } )
    7.db.myColl.find( { category: “cafe” } )
  2. db.myColl.createIndex(
    { score: 1, price: 1, category: 1 },
    { collation: { locale: “fr” } } )
  3. db.myColl.find( { score: 5, category: “cafe” } )

照片 2018-03-27 下午8.06.04

高端方法

selenium


def get_html():
    driver=webdriver.Firefox()
    html=driver.get('https://search.jd.com/search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&gp=2&cid2=653&cid3=655&ev=exbrand_%E4%B8%89%E6%98%9F%28SAMSUNG%29%5E&page=1&s=1&click=0')
    time.sleep(3)
    driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
    time.sleep(3)
    html = driver.find_element_by_xpath("//*").get_attribute("outerHTML")
    return html


python shell

  1. client=MongoClient(‘localhost’,27017)
  2. db = client.primer

  3. db.webpage.find()找出collection爲webpage的所有元素
    . tablename.remove({“name”: “mike”})

  4. counts=table_name.count()
    coll = db.dataset

刪除數據庫

client

  • 查看錶中有多少元素
    counts=table_name.count()
    print(‘總行數:%s’%counts)

  • 找到一條記錄
    cols=table_name.find_one()

  • 找特定的某一行

result=table_name.find({“name”:”fanjialiang”})

連接到對應的數據庫

連接數據庫名爲primer
db = client.primer
連接名稱爲dataset的collctions
coll = db.dataset

db=conn.get_database('local')
colletion=db.collection_names()

查找

result=db.webpage.find({‘url’:url})//查找出來的是遊標

  • result=db.webpage.find_one({‘_id’:url})
    result= ‘ads’
    for i in result:
    print(i)

將url設爲id

db.webpage.update({‘_id’:url},{‘$set’:{‘html’:html}},upsert=True)

刪除

 tablename.remove({"name": "mike"})
  • 插入
    table_name.insert({“name”:’fanjialiang’,”age”:18})

ps aux | grep mongo 查看mongodb 然後kill掉


requests

請求格式

response=requests.get(url=self.begin_url,headers=self.headers,cookies=CookieJar)

下載文件:

url=http://flupy.org/data/flags/fr/fr.gif

iamge=request.get(url).content

open(‘a.gif,’wb’) as opener:

opener.write(image)

解析csv文件

file=open(‘csv/top-1m.csv.zip’,’r’)
with ZipFile(file) as zf:
csv_filename=zf.namelist()[0]
for _,website in csv.reader(zf.open(csv_filename)):
urls.append(‘http://’+website)

下載最受歡迎的網站

下載一千個網頁:
- 如果國內訪問不到,設置一個超時時間,返回url,添加在錯誤url list中
- 如果能訪問到,加在mongo數據庫中,並且爲加入的url,創建一個index序號,作爲主鍵
- 計算訪問花費的總時間。
- 設置數據庫名稱
- 回調函數先不創建



代理項目

  1. 不斷的從互聯網上抓取代理
  2. 將抓取下來的代理寫在csv中
  3. 將好的代理篩選出來,返回一個List
  4. 抓取其他網站時,採用從代理池中隨機選擇一個

百度貼吧項目

  1. 將title抓下來
    將內容抓下來
    然後打印title,和對應的內容

每打印一行,輸出換行

2.將頁數抓下來,維持一個隊列,每次從隊列中取url,如果沒訪問過加加在隊列中,否則跳過。

  1. 將抓下來的內容存放在mongoDB中 起名NBA50大

抓取淘寶模特信息

  1. 在主頁面把模特的href 抓下來,然後進入每個的個人頁面href

  2. 進入網頁後,抓取個人域名,在進入每個人的個人域名把照片抓取下來

  3. 在個人頁面上,把個人信息抓取下來,儲存爲csv文件
    身高, 三圍 , 個人頁面, 等等

項目流程

  • downloader類負責下載 不要scrapeCallback方法了

  • hrottle類負責 限制速度

  • scrapeCallback爲回調類,在完成下載後調用回調類將消息寫入硬盤

  • diskCache 類負責將抓取的內容寫到硬盤中

  • Link_crawler爲總的開始

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章