tensorflow精进之路(十八)——python3网络爬虫(中)

1、概述


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

2、打开待爬取网页


打开汽车之家官网,

https://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 = "https://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请求,如下图所示,

 

 

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

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

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

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

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

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

https://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 = "https://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 = "https://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)

 


总结:

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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值