实践才是检验真理的唯一标准-爬虫制作(二)

前言:

有很多时候觉得自己很忙碌,其实都是自己拖拉造成的,让自己效率提升才是解决问题的关键性。
来吧,以后一切的种种。

目标:

既然已经学会了爬取网页的基本信息,就不能单纯的满足于几个网页的爬取。这次我们要更多更快更高效的完成任务。上次我们学习选择的是58同城,这次我们就选择和58同城相似的页面:赶集网。

实践才是检验真理的唯一标准-爬虫制作(二)_第1张图片
免费赠送都是什么鬼

爬取每一个大标题里的内容信息。例如

实践才是检验真理的唯一标准-爬虫制作(二)_第2张图片
一元抢iPhone都是骗人的,会有人信?

由于上次没有模块化,以及因为数据量太小没有用到数据库,这次我们就选择mongodb来作为我们的数据库,mongodb 这个就是官网,找到绿色的download键,根据自己电脑版本选择下载包。win7的小伙伴们记得下载这个补丁包补丁点我 ,安装mongoddb完成后,就要进行配置。
(1):创建一个存放数据的地址,在cmd中输入 md c:\data\db
(2):启动mongodb,cmd中输入 c:\xxx\xxx\xxx\mongod.exe 这里的xxx是你的安装目录
(3):连接mongodd 不要关闭(2)的窗口,开启一个新的cmd,输入c:\xxx\xxx\xxx\mongo.exe,看到了welcome to mongodb shell就说明你已经启动成功啦!
(4):为了让mongodb开机自启动,我们要写一个简单的配置文件,在cmd中输入mkdir c:\data\log 关闭cmd,在文件夹下面建一个文件,命名为mongod.cfg,内容为:
systemLog:
    destination: file
    path: c:\data\log\mongod.log
storage:
    dbpath: c:\data\db
保存,打开一个cmd 输入"c:\xxx\xxx\xxx\mongod.exe" --config "你cfg文件存放的位置" --install
结束后输入net start MongoDB 。到这里mongodb安装就完成了,接下来就在ide中对其进行配置:
(1):安装在pycharm中pymongo,第一篇文章有写第三方的安装这里就不多赘述。
(2):安装插件,在pycharm中setting

实践才是检验真理的唯一标准-爬虫制作(二)_第3张图片
点Uninstall那个位置的按钮

(3):

实践才是检验真理的唯一标准-爬虫制作(二)_第4张图片
勾选上Tool buttons

(4)配置

实践才是检验真理的唯一标准-爬虫制作(二)_第5张图片
点击小扳手

(5):

实践才是检验真理的唯一标准-爬虫制作(二)_第6张图片
点击绿色的小加号

label里填一个自己起的名字,server url中如图所示,然后点ok。这时候我们就完成了整个的配置。

进入正题:

首先,选出提取出每一个频道的地址

实践才是检验真理的唯一标准-爬虫制作(二)_第7张图片
检查

右键检查,观察后发现规律:

from bs4 import BeautifulSoup

import requests

main_url ='http://bj.ganji.com/wu/'

web_data = requests.get(main_url)

web_data.encoding ='utf-8'

soup = BeautifulSoup(web_data.text,'lxml')

url = soup.select('dl > dt > a')      在dl标签下的dt标签里的a标签中 绕口令

这样我们就能把url都提取出来,这里,我为了以后使用方便,把提取出来的url放在一个list中,命名为urls。
既然有了数据库,我们就可以分成两个爬虫来写,一个提取页面中商品的url信息。另一个函数爬取具体信息。所以建立两个数据表:

client = pymongo.MongoClient('localhost',27017)

ganji = client['ganji']

url_list = ganji['url_list']     存放url

item_info = ganji['item_info'] 存放具体信息

为了让每个模块的功能清晰可见。我们分为几个部分来写

实践才是检验真理的唯一标准-爬虫制作(二)_第8张图片
赶集

urls存在select—channel中
获取网址和获取信息存放在get_inf中
为了防止大量爬取的时候被58封ip,自定义一下header以及ip地址

headers  = {

xxxx                                 这里请小伙伴们自己填写

}

proxy_list = [

'http://xxxxx',                   ip地址也同样

'http://xxxxx',

'http://xxxxx',

]

proxy_ip = random.choice(proxy_list)           随机选择ip

proxies = {'http': proxy_ip}

首先先完成提取url的工作

def get_url(channel, page):                    定义两个参数,第一个为select_channel中的url,第二个为提取第几页
    main_url = channel +'o{}'.format(page)        观察网页如http://bj.ganji.com/jiaju/o6/,可以知道网页的构成模式为channel和页数相拼接而成

    web_data = requests.get(main_url)

    time.sleep(1)          休眠一秒钟,防止速率过快

    soup = BeautifulSoup(web_data.text,'lxml')

    url = soup.select(' div > ul > li.js-item > a')       选出每个商品的链接  

    if soup.find('div','pageBox'):                           这里如果页面太过于往后,就会只显示广告,为了不选择广告。观察发现,只有正常的页面里才有翻页这个功能,而广告页没有,所以选出带有"page_box"的网页

        for link in url:

            link = link.get('href')

            urls = {

            'url': link

            }

            url_list.insert_one(urls)            通过for循环把网页地址存入数据库中

    else:

        pass

完成了对网页的筛选以后,我们来写第二个爬虫。来进行对具体信息的爬取:
def get_inf(url):

    str =""

    web_data = requests.get(url)

    soup = BeautifulSoup(web_data.text,'lxml')

    if soup.find('div','error'):                    网页如果出现404,跳出

        pass

    elif soup.find('p','error-tips1'):           网页若果出现物品不存在的错误,跳出

        pass

    else:

        print(url)                                   调试用的

        times = soup.select('i.pr-5')                检查网页得到的

        leixing = soup.select('ul.det-infor > li:nth-of-type(1) > span > a')     同上

        places = soup.select('div > ul.det-infor > li:nth-of-type(3) > a')          同上

        money = soup.select('div.leftBox > div:nth-of-type(3) > div > ul > li:nth-of-type(2) > i')         同上

        xinjius = soup.select('div > div:nth-of-type(1) > ul.second-det-infor.clearfix > li')

        for place in places:                    处理地点的字符串

            str = str + place.text +''

        if(xinjius):                   对新旧程度的处理

            xinjius = xinjius[0].text.split('(')[0].replace('\n','').replace(' ','').split(':')[-1]

        else:

            pass

        if(times):                     对时间的处理

            times = times[0].text.replace(' ','').replace('\n','').replace('\xa0','').split('发')[0]

        else:

            pass

        if(leixing):                      对类型的处理

            leixing = leixing[0].text

        else:

            pass

        if(money):               对价格的处理

            money =int(money[0].text)

        else:

            money ='未填写'

        data = {

            '标题': soup.title.text.strip(),

            '时间': times,

            '类型': leixing,

            '位置': str,

            '价格': money,

            '新旧': xinjius

        }

        item_info.insert_one(data)          写入数据库

这样就完成了对具体信息的爬取。
下一步我们写一个main函数,来进行调度

from ganji.select_channel import *            引用包

from ganji.get_inf import *

from multiprocessing import Pool              引用多进程

def all_links(channel):

    for href in channel:

        for i in range(1,11):                             获取前十页的信息,如果获取100页即为range(1,,101)

            get_url(href,i)                                      调用第一个爬取网址的爬虫

def start_get (link):

    pool = Pool()

    pool.map(get_inf, link)                                     使用多线程并调用第二个爬取信息的爬虫

if__name__ =='__main__':                                     主函数

    all_links(urls)                                               调用上文定义的函数

    link = []                                                         设定一个list存放从网址

    for hrefs in url_list.find():                            

        canshu = hrefs['url']                        

        link.append(canshu)                               把网址存入list中

    start_get(link)                                               调用上文函数

最后的最后,我们要写一个计数程序来检测已经爬取了多少数据

import time

from ganji.get_inf importurl_list

from ganji.get_inf import item_info

    while True:                 死循环

        print("网址")

        print(url_list.find().count())                  输出网址数

        print("数据")                                            

        print(item_info.count())                       输出数据数

        time.sleep(5)

这样我们的程序就基本完成了,我们来看看结果:


实践才是检验真理的唯一标准-爬虫制作(二)_第9张图片
原来是这么简单的事情

题后记:

做中学,私以为是一种学习编程的最好的办法了。这次的程序的缺点,我认为有以下几点:
(1)参数命名问题。
(2)一万多条网址只爬取了四千多条信息,pass语句使用太多,应该更好的处理信息。
(3)爬取数量应该更多一些。应做到十万条的测试

你可能感兴趣的:(实践才是检验真理的唯一标准-爬虫制作(二))