首页 > 代码库 > 使用beautifulsoup与requests爬取数据

使用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 = http://www.mamicode.com/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 = http://www.mamicode.com/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=http://www.mamicode.com/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/

 

使用beautifulsoup与requests爬取数据