python爬虫个人小结

如题,直接上代码,代码中有部分注释。

对以文字为主的页面进行抓取

正则式的文章之前已经写过很多次了,别人的博客也介绍了很多,不再赘述。

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

#代理服务器地址:http://www.xicidaili.com/
def use_proxy(proxy_addr, url):
    proxy = ur.ProxyHandler({'http':proxy_addr})
    opener = ur.build_opener(proxy, ur.HTTPHandler)
    ur.install_opener(opener)
    #设置超时
    data = ur.urlopen(url, timeout=30).read().decode('utf-8')
    return data
import urllib.error as ue

try:
    #使用代理服务器的ip爬取,防止自己的ip地址在多次异常访问网站后被封禁
    proxy_addr = '121.196.218.197:3128'
    url = 'https://blog.csdn.net/rookie_wei'
    data = use_proxy(proxy_addr, url)
    
    #伪装爬虫,模拟浏览器访问
#     req = ur.Request(url)
#     header = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'
#     req.add_header("User-Agent", header)
#     data = ur.urlopen(req).read()

    print(data)

except ue.URLError as e:
    print('URL error', e.code, e.reason)

有两个问题需要注意:

第一,有些网页是动态刷新的,也就是说你正常爬只能爬到最前面的一部分。解决方法:一般这种网址都是由相同的主体部分构成,然后再加一下个性化的后缀形成一个完整的url。人工找出个性化后缀的规律,然后尝试用loop解决。

第二,有些网页不是utf8格式。解决方法:需要先解码然后转成utf8格式处理。

html1 = ur.urlopen(req, timeout=600).read()
html1 = str(html1.decode('gbk'))

对以图片为主的页面进行抓取

有三个问题需要注意:

第一,图片查重。如果重复图片是连续出现的(比如每一张图片都连续出现2次)。解决方法:注意同一张只爬一遍。大部分都是这种情况。混乱顺序的重复图片没办法查。

第二,url中不能带有中文。解决方法:尝试替换成相应的英文。或者,用urllib.request.quote()进行更高级的转换编码,见代码。

import string
url1 = 'https://image.baidu.com/search/index?tn=baiduimage&word=大学'
ur.quote(url1, safe=string.printable)

得到新的url:'https://image.baidu.com/search/index?tn=baiduimage&word=%E5%A4%A7%E5%AD%A6'

同理,可以使用unquote()进行反转码。

第三,找不到图片的链接。解决方法:需要人工尝试,寻找到每张图片url的规律。看起来很多图片的url十分复杂,但是大部分的参数(导致url不同的部分)是没有用的(至少对于打开图片没有帮助),可以忽略。找到真正区别不同图片的那几个参数,然后写loop就好了。

多线程爬取

多线程爬取更加快速。

import threading
 
class A(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
 
    def run(self):
        for i in range(1000):
            print('我是线程A')
 
 
class B(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
 
    def run(self):
        for i in range(1000):
            print('我是线程B')
 
t1 = A()
t1.start()
 
t2 = B()
t2.start()

参考博客:

猜你喜欢

转载自blog.csdn.net/qq_40136685/article/details/98381188