关于初学python爬虫的一点问题总结(一)

关于初学python的一点问题总结(一)

目录


总结

这几天看了一下《python网络数据采集》,跟着书上差不多看了前面三章然后完成了一点书上的代码,这本书都是基于3.0以上的版本在写的,中间插入scrapy框架又需要用2.7版本。

页面抓取

首先是对整个html页面的抓取:

from urllib.request import urlopen
html=urlopen("http://baike.baidu.com")
print(html.read())

这个样子基本就可以拿下网页的html并输出到控制台上。

开始使用BeautifulSoup

通过python3中自带的pip程序(程序在\Python\Scripts),在cmd中运行,如图所示:

添加bs4

添加之后进行引用,然后就可以对页面DOM树直接进行操作,代码如下:

from bs4 import BeautifulSoup
from urllib.request import urlopen
html=urlopen("http://baike.baidu.com")
bsObj=BeautifulSoup(html.read(), "html.parser")
print(bsObj.title)

根据标签属性抽取数据

在BeautifulSoup的对象当中,通过find()和findAll()方法查询,产生Tag对象。然后使用Tag.get_text()就可以输出标签内容。具体的方法如下:

bsObj.findAll("div",{"class":"content"})
bsObj.findAll(class_="content")

对于兄弟,父母或者子标签,分别有对应的方法使用:.next_siblings() .parent 以及 .children

正则表达式

在某些标签的筛选中,可以使用正则表达式对特定的字符串进行筛选。这里有一个测试正则表达式的网站:RegexPal
关于正则表达式,具体的内容不再阐述,很多博客都有讲解。

开始过滤单个页面获取信息

首先通过遍历百度百科某个页面,结合正则表达式,并获取其中指向内部的<a>标签

from bs4 import BeautifulSoup
from urllib.request import urlopen
import re

html=urlopen("http://baike.baidu.com/item/%E8%B5%B5%E6%B0%8F%E5%AD%A4%E5%84%BF/13828701")
bsObj=BeautifulSoup(html.read(), "html.parser")
btnList=bsObj.find("div",{"class":"body-wrapper"}).findAll("a",href=re.compile("^(/item/|/view/)"))
for btn in btnList:
    if 'href' in btn.attrs:
        print(btn.get_text())
        print(btn.attrs['href'])

输出结果如下:
这里写图片描述

开始抓取内部链接数据

接下来就是开始对整个百度百科进行抓取,并将抓取内容输出到txt文件里面。代码如下:

# -*- coding: utf-8 -*-
import sys
from urllib.request import urlopen
from bs4 import BeautifulSoup
import datetime
import random
import re

# sys.setdefaultencoding('utf-8')

def getLinks(aUrl):
    global pages
    html=urlopen("http://baike.baidu.com"+aUrl)
    bsObj=BeautifulSoup(html.read(),"html.parser")
    links=bsObj.find("div",{"class":"body-wrapper"}).findAll("a",href=re.compile("^(/item/|/view/)"))
    urlcontent=bsObj.find("div",{"class":"para"}).get_text()+"\n"
    print("content:"+urlcontent)
    f=open("baike.txt","a+",encoding='utf-8')
    f.write(urlcontent)
    for link in links:#开始抽取<a>标签的属性
        if 'href' in link.attrs:
            if link.attrs['href'] not in pages:
                list=link.get_text()+" "+link.attrs['href']+"\n"
                print(list)
                f.write(list)
                pages.add(link)
        if link.attrs['href']=="/view/10812319.htm":#如果跳转到死链接就将链接初始化
            link.attrs['href']="/item/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98"
    f.close()
    return links

random.seed(datetime.datetime.now())
pages=set()
links=getLinks("/item/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98")
while len(links)>0:
    newArt=links[random.randint(0,len(links)-1)]
    newArthref=newArt.attrs['href']
    newArttitle=newArt.get_text()
    result='----->'+newArttitle+' '+newArthref+"\n"
    print("==============")
    print(result)
    f=open("baike.txt","a+",encoding='utf-8')
    f.write(result)
    f.close()
    print("==============")
    links=getLinks(newArthref)

整个代码将会开始进行一个死循环,然后开始持续抓取数据,然后将抓取的内部链接写进文本中。

最后说点

代码中间会产生重复的数据,将会在下次更新博客的时候解决。
写入文件时候的编码问题,在写入txt的时候,默认的txt文件编码为ANSI,需要先把txt的编码改变为utf-8,才能写入,否则会出现乱码。
内存溢出问题,在持续循环的时候,由于访问页面的增加,其中的request和response对象会直接存放在内存当中,这样会造成内存溢出,解决方案留在下次更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值