发表文章

[最新] tensorflow入门笔记(十八)python3网络爬虫(中)

rookiewei 2月前 0

1、概述

上一节简单的介绍了一些python3网络爬虫的知识,这一节就运用上一节的知识写个小demo,用于爬去汽车之家网站的汽车厂商及车型名称。

2、打开待爬取网页

打开汽车之家官网,

http://www.autohome.com.cn

点击按品牌找车按钮,


得到以下界面,


这就是我们要爬取的内容。

3、调试窗口的使用

“F12”或者“ctr+shift+i”打开浏览器的调试工具,

点击左上角按钮,然后可以看到鼠标选中网页哪个控件时,哪个控件相应的HTML代码就显示在“Inspector”窗口,我们点击奥迪的图标,获取这个标签的源码,


可以看到,我们鼠标放在哪段代码上面,那段代码对应的网页标签会被标亮,如下图所示,


4、寻找规律

首先,我们要明确我们想爬什么内容,比如这个例子中,我们想爬取的是汽车厂商及车型名称,以奥迪为例,如下图所示,我们想爬的内容是奥迪一汽-大众奥迪奥迪Q5L”奥迪A3”等等,所以我们应该找到每个待爬取元素的标签的规律。

首先来看品牌名奥迪的标签,其HTML代码如下,


<dt></dt>标签里面就包含了奥迪图标和奥迪名称,我们要获取的只是奥迪这两个字,但是目前好像还看不出它有什么明显的标志(如class或者id)让我们获取。往下看看阿斯顿.马丁,如下图所示,

我们发现它也是包含在<dt></dt>标签里面,这就是规律。

接着往下看看品牌厂商一汽-大众奥迪有没有什么规律,其代码如下,


可以看到,这个就有比较明显的标志的,比如class=”h3-hit”,下面的“Audi Sport”奥迪进口是同样class。再看看车型名的代码,

从上面的代码看到,车型名并没有厂商名那么明显的标志,它包含在<h4></h4>标签里。多看几个车型名的源码就会发现,所有的车型名都包含在<h4></h4>标签里,这就是规律。

接着我们看以字母B开头的厂商的规律是否我们上面判断的一样呢?

鼠标往下滚动,看看奔驰的,品牌名的源码如下,


确实也是包含在<dt></dt>标签里面,然后再看厂商名北京奔驰,车型名奔驰C,跟我们上面发现的规律是一样的。

5、代码实现

发现规律以后,就可以写代码去爬取了,

5.1、导如模块,并爬取整个网页

#encoding:utf-8
import urllib.request as ur
import re

url = "http://www.autohome.com.cn/car/"
req = ur.Request(url)
req.add_header("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0")
html1 = ur.urlopen(req, timeout=600).read()
html1 = str(html1)
print(html1)

运行结果如下,

5.2、使用正则表达式将所有<dt></dt>、<div class="h3-tit"></div>、<h4></h4>标签匹配出来

pat1 = '<dt>.+?</dt>'
pat2 = '<div class="h3-tit">.+?</div>'
pat3 = '<h4>.+?</h4>'
manufacturers = re.compile(pat1 + '|' + pat2 + '|' + pat3).findall(html1)

for manufacturer in manufacturers:
    print(manufacturer)

运行结果如下,

我们看运行结果的最后一行,爬出来的车型是“RG Nathalie”,在网页里搜索,结果如下图所示,

这个车型只是A字母的最后一个车型。为什么会这样呢?

5、继续寻找规律

继续看源码,如下图所示,

id=”boxA”的标签包含的是字母A开头的品牌,id=”boxB”的标签包含的是字母B开头的品牌,以此类推。我们看到,除了boxA以外,都有个style=”display:none”的属性,说明这些是隐藏的,我们打开boxB来看看。


果然里面是没有内容的。鼠标滚轮往下翻网页,浏览到字母B开头的品牌时,再看源码就有内容了,


这说明网页是动态刷新的,浏览到哪个字母才刷新。

选则“Network”窗口,然后点击左上角清除窗口的内容。

鼠标滚轮继续往下滚动到字母C开头的品牌区,果然是对服务器有GET请求,如下图所示,


点开这个请求,复制HeadersRequest URL里的内容:

http://www.autohome.com.cn/grade/carhtml/C.html

打开这个链接,如下图所示,

果然跟我们想的一样,鼠标滚轮继续往下滚动,就会得到如下链接,

http://www.autohome.com.cn/grade/carhtml/D.html

http://www.autohome.com.cn/grade/carhtml/E.html

http://www.autohome.com.cn/grade/carhtml/F.html

等等链接。

可以找到规律了,前面的URL都是一样,末尾的D.html表示字母D开头的品牌,以此类推,所以,我们只需要爬取这些网页的内容即可。

8、继续写代码

对上面代码稍加修改,

#encoding:utf-8
import urllib.request as ur
import re

def get_car_model_name(url):
    req = ur.Request(url)
    req.add_header("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0")
    html1 = ur.urlopen(req, timeout=600).read()
    html1 = str(html1)

    pat1 = '<dt>.+?</dt>'
    pat2 = '<div class="h3-tit">.+?</div>'
    pat3 = '<h4>.+?</h4>'
    manufacturers = re.compile(pat1 + '|' + pat2 + '|' + pat3).findall(html1)

    for manufacturer in manufacturers:
        print(manufacturer)


url = "http://www.autohome.com.cn/grade/carhtml/"

for page in range(ord("A"), ord("Z") + 1):
    print(url + chr(page) + ".html")
    get_car_model_name(url + chr(page) + ".html")

运行结果:

运行结果跟之前的不一样,但是得到的是“\xd5\xfd\xb5\xc0K550”这种乱码的东东,所以还的进行字符转码,将上面代码的,

html1 = str(html1)

改成

html1 = str(html1.decode('gbk'))

在运行,得到结果,


可以看到,最后一个车型名是正道K550”,我们去网页看看最后一个车型是不是这个?

果然是对了。但是我们现在并没有提取出我们想要的数据,这些数据还包含了像

这些我们不需要的东西,所以还的进一步过滤,

首先来看品牌名,


从上图可以看到,品牌名是包含在<dt></dt>标签中的,

车型名在<h4></h4>标签中,根据这些特征,我们就可以将他们分离出来,然后再提取。

将上面for manufacturer in manufacturers:的代码改为,

for manufacturer in manufacturers:
    if manufacturer.find('</div></dt>') > 0:
        manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
        manufacturer = "品牌名===" + manufacturer + "\n"
        print(manufacturer)
    elif manufacturer.find('h3-tit') > 0:
        manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
        manufacturer = '厂商名------' + manufacturer + "\n"
        print(manufacturer)
    elif manufacturer.find('</h4>') > 0:
        manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
        manufacturer = '车型名>>>>>>>>>>' + manufacturer + "\n"
        print(manufacturer)

运行结果:

从运行结果中看到,品牌名提取到的是品牌的图片链接了,厂商名和车型名没问题,那么,品牌名得再修改,再次看看品牌名的HTML源码,


我们根据<dt></dt>标签提取品牌名所在的区域,然后再根据 ”>品牌名</ 来提取品牌名,但是看代码,符合这个特征的不知是品牌名,还有品牌的图片,

因此,我们还得进一步提取,将

pat1 = '<dt>.+?</dt>'

改成

pat1 = '<div><a href=.+?</a></div></dt>'

再运行代码,运行结果为,


这下就对了,再看网页发现,有些停产或者未上市的车型是黑色的,如下图,

我们可以再将车型细分,将在售车型和未售车型分开,


查看源码发现,未售车型多出class=”greylink”的标签,根据这个就可以提取,代码如下,

for manufacturer in manufacturers:
    if manufacturer.find('</div></dt>') > 0:
        manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
        manufacturer = "品牌名===" + manufacturer + "\n"
        print(manufacturer)
    elif manufacturer.find('h3-tit') > 0:
        manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
        manufacturer = '厂商名------' + manufacturer + "\n"
        print(manufacturer)
    elif manufacturer.find('</h4>') > 0:
        if manufacturer.find('greylink') < 0:
            manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
            manufacturer = '>>>>>>>>>>(在售)' + manufacturer + "\n"
            print(manufacturer)
        else:
            manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
            manufacturer = '>>>>>>>>>>(未售)' + manufacturer + "\n"
            print(manufacturer)

运行结果,

当然,还可以将其保存到文件中。

9、完整代码

#encoding:utf-8
import urllib.request as ur
import re
import codecs

def get_car_model_name(url, fd):
    req = ur.Request(url)
    req.add_header("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0")
    html1 = ur.urlopen(req, timeout=600).read()
    html1 = str(html1.decode('gbk'))

    pat1 = '<div><a href=.+?</a></div></dt>'
    pat2 = '<div class="h3-tit">.+?</div>'
    pat3 = '<h4>.+?</h4>'
    manufacturers = re.compile(pat1 + '|' + pat2 + '|' + pat3).findall(html1)

    for manufacturer in manufacturers:
        if manufacturer.find('</div></dt>') > 0:
            manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
            manufacturer = "品牌名===" + manufacturer + "\n"
            print(manufacturer)
        elif manufacturer.find('h3-tit') > 0:
            manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
            manufacturer = '厂商名------' + manufacturer + "\n"
            print(manufacturer)
        elif manufacturer.find('</h4>') > 0:
            if manufacturer.find('greylink') < 0:
                manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
                manufacturer = '>>>>>>>>>>(在售)' + manufacturer + "\n"
                print(manufacturer)
            else:
                manufacturer = manufacturer[manufacturer.find('">') + 2: manufacturer.find("</")]
                manufacturer = '>>>>>>>>>>(未售)' + manufacturer + "\n"
                print(manufacturer)

        fd.write(manufacturer)

url = "http://www.autohome.com.cn/grade/carhtml/"
with codecs.open("汽车之家车型.txt", "w", 'utf-8') as fd:
    for page in range(ord("A"), ord("Z") + 1):
        print(url + chr(page) + ".html")
        get_car_model_name(url + chr(page) + ".html", fd)

总结:

以上就是一个简单的爬虫,可以看到,爬取特定数据的爬虫其实就是解析网页的过程。发现其规律,然后爬取网页,解析数据。下一节就去爬百度图片,获取后续需要训练的图片。


相关推荐
最新评论 (0)
返回
发表文章
rookiewei
文章数
49
评论数
0
注册排名
773533