使用beautifulsoup與requests爬取數據


1、安裝需要的庫

bs4 beautifulSoup  requests lxml
如果使用mongodb存取數據,安裝一下pymongo插件

2、常見問題

1> lxml安裝問題

如果遇到lxml無法安裝問題,參考知乎上的答案:

首先,安裝wheel,命令行運行:pip install wheel
其次,在這里下載對應的.whl文件,注意別改文件名!http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml
Ctrl + F,輸入lxml,找到下面這段Lxml,
Lxml, a binding for the libxml2 and libxslt libraries.
lxml‑3.7.1‑cp27‑cp27m‑win32.whl

lxml‑3.7.1‑cp27‑cp27m‑win_amd64.whl

lxml‑3.7.1‑cp34‑cp34m‑win32.whl

lxml‑3.7.1‑cp34‑cp34m‑win_amd64.whl

lxml‑3.7.1‑cp35‑cp35m‑win32.whl

lxml‑3.7.1‑cp35‑cp35m‑win_amd64.whl

lxml‑3.7.1‑cp36‑cp36m‑win32.whl

lxml‑3.7.1‑cp36‑cp36m‑win_amd64.whl
cp后面是Python的版本號,27表示2.7,根據你的Python版本選擇下載。
之后, 進入.whl所在的文件夾,執行命令即可完成安裝pip install 帶后綴的完整文件名

2> pip問題
如果提示 'pip' 不是內部或外部命令,也不是可運行的程序。

多是因為環境變量沒有設置好。需要設置兩個,一些常用的命令在Scripts文件夾下面

以下兩個改為自己計算機的路徑

C:\Files\Python\Python36
C:\Files\Python\Python36\Scripts

3、mongodb

如何安裝mongodb參見https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

服務啟動與停止

sudo service mongod start
sudo service mongod stop
sudo service mongod restart

配置文件位於 /etc/mongod.conf,默認端口 27017 ,修改可以在配置文件中修改

# network interfaces
net:
  port: 27017
#  bindIp: 127.0.0.1

此外,默認綁定了ip地址127.0.0.1,需要將此句注釋掉,否則遠程無法訪問

4、參考代碼

import requests
from bs4 import BeautifulSoup
import time
import pymongo
import random
from multiprocessing import Pool
# 導入多個對象或者函數用逗號分開
# from test_parsing import get_items,url_list

# mongodb客戶端
client = pymongo.MongoClient('192.168.1.101',27017)
# 數據庫
test = client['testdata']
# 各種表
tb = test['testtable']
mb= test['itemtable']
detail= test['detailtable']

headers  = {
User-Agent:
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
    'Connection':'keep-alive'
}


proxy_list = [
    'http://118.79.27.123:8081',
    'http://113.108.253.195:9797',
    ]

# 隨機獲取代理ip
proxy_ip = random.choice(proxy_list) 
proxies = {'http': proxy_ip}

# 簡單用例
def get_pages_within(pagenums):
    for page_num in range(1,pagenums+1):
        # 請求
        wb_data = requests.get('http://urldata/test/pn{}/'.format(page_num))
        # 包裝一個對象
        soup = BeautifulSoup(wb_data.text,'lxml')
        # 使用select方法,參數為樣式選擇器,div.price_li > span 標識逐層級關系,div.price_li span 只是簡單的包含關系        
        numbers = soup.select('div.number')
        prices = soup.select('span.price')
        
        links = soup.select('a.t')

        for number, price, link in zip(numbers,prices,links):             
            if int(price.get_text()) > 500:
                print(number,price)
            data = {
                'title':number.get_text(),
                'price':price.get_text(),
                'link' :link.get('href')
            }
            tb.insert_one(data)
        print('finished')

# 復雜點的
def get_links_from(source, pages, flag='c'):
    list_view = '{}{}{}/'.format(source, str(flag), str(pages))
    # 帶參數
    wb_data = requests.get(list_view,headers=headers,proxies=proxies)
    soup = BeautifulSoup(wb_data.text, 'lxml')
    if soup.find('ul', 'pageLink'):
        for link in soup.select('.fenlei dt a'):
            item_link = link.get('href')
            mb.insert_one({'url': item_link})
            print(item_link)
            
    else:
        pass


def get_detail_from(url,data=None):
    wb_data = requests.get(url,headers=headers)
    time.sleep(1)
    # flag = 'flagnumber' in soup.find('script', type="text/javascript").get('src').split('/')
    # if flag: 
    if wb_data.status_code == 404:    
        pass
    else:
        soup = BeautifulSoup(wb_data.text, 'lxml')
        data = {
            'title':soup.title.text.strip(),
            'price':soup.select('div.price_li > span > i')[0].text.strip(),
            'time':soup.select('.pubtime')[0].text.strip().split('/')[0],
            'area':list(map(lambda x:x.text,soup.select('ul.area-infor > li > a'))),
            'cates':list(soup.select('div.cates > span > i')[0].stripped_strings),
            'url':url
        }       
        detail.insert_one(data)

source_list = '''
http://test.com/books/
http://test.com/pictures/
'''

# 讀取數據
# $lt/$lte/$gt/$gte/$ne,依次等價於</<=/>/>=/!=。(l表示less g表示greater e表示equal n表示not  )
for item in detail.find({'price': {'$lt': 100}}):
    print(item)
    
for i in detail.find():
    if i['price'] >= 500:
        print(i)

if __name__ == '__main__':
    # 使用多進程
    pool = Pool()
    # pool = Pool(processes=2)
    if source_list is not None:
        pool.map(get_links_from,source_list.split())
    
    pool.close()
    pool.join()

一般使用谷歌瀏覽器對要爬取的元素進行檢查,在這一方面,好用一些,右鍵,選擇Copy selector,獲取到例如:div.cates > span > i,作為select函數的參數即可。

 也可以自己寫,在瀏覽器的檢查元素頁面上,ctrl + F 出現查找框,寫入要使用的樣式選擇器,看看是否准確即可 。

例子:div.price_li > span 標識逐層級關系,div.price_li span 只是簡單的包含關系

 

 

 5、參考文檔

http://beautifulsoup.readthedocs.io/zh_CN/latest/

http://www.python-requests.org/en/master/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM