8.2 IP代理实战1:用Requests 库爬取公众号文章(提取的网址不全的处理,日期为时间戳格式的处理,乱码的处理)

  • 搜索微信(https://weixin.sogou.com/)是一个微信公众号的搜索引擎,如下图所示。只需在搜索框中输入关键词,单击“搜文章”按钮,即可搜索微信公众号文章。本节要用Requests库从搜狗微信爬取微信公众号文章。
    在这里插入图片描述
  • 爬取微信公众号文章时,如果爬取频率不高,如一天只爬几十次或几百次,不用IP代理也能完成;如果爬取频率较高,那么最好使用IP代理。下面会先不用IP代理进行爬取,再添加IP代理进行爬取,最后通过搭建只能IP切换系统让爬取更加顺利。

8.2.1 直接用Requests库爬取

  • 用Requests库爬取微信公众号文章的基本思路没有特别之处,主要有四步:(1)获取网页源代码;(2)解析和提取需要的数据,如标题、日期等;(3)数据清洗及打印输出;(4)定义函数并批量调用。

1.获取网页源代码

import requests
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'}
url = 'https://weixin.sogou.com/weixin?type=2&query=阿里巴巴'
res = requests.get(url,headers=headers,timeout=10).text
print(res)
  • 运行后打印输出的结果中没有乱码,并且包含需要的数据,所以第一步就算完成了。

2.编写正则表达式提取数据

  • 接下来需要从获取的网页源代码中提取所需数据,可以用正则表达式或BetifulSoup库来完成。这里用正则表达式提取文章的标题、网址、来源、日期。
(1)标题
p_title = 'uigs="article_title_.*?">(.*?)</a>'
(2)网址
  • 网址的提取稍微有些难度。首先要提取下图中<a>标签中href属性值。
    在这里插入图片描述
  • 观察href属性值前后的网页源代码,可以找到如下规律:
<div class="txt-box">换行<h3>换行<a target="_blank" href="网址的一部分"
  • 这里用.*?代替换行,编写的正则表达式如下:
p_href = '<div class="txt-box">.*?<h3>.*?<a target="_blank" href="(.*?)"'
  • 这里有两点需要注意:一是因为使用“.*?”来匹配换行,所以之后在findall()函数中需要天骄re.S修饰符(或者用“\n”代替“.*?”来表示换行);二是因为提取的网址并不完整,是格式类似“/link?url=xxx”的内容,还缺少域名“https://weixin.sogou.com”,之后数据处理时需要加上。

  • 有的读者可能会问:为什么不用如下所示的正则表达式来提取网址呢?这是因为这种写法过于简单,网页源代码中其他网址也符合其规律,所以很容易匹配到一些不需要的内容。

p_href = '<<a target="_blank" href="(.*?)"'
(3)来源
p_source = 'uigs="article_account_.*?">(.*?)</a>'
(4)日期
  • 日期的提取也有一定难度,不感兴趣的读者可以直接跳过分析过程,直接使用最后的完整代码。用开发者工具能看到常规格式的日期,如“2022-4-11”,如下图所示。

在这里插入图片描述

  • 但是在Python 获取的网页源代码中却找不到日期“2022-4-11”,这是因为它是以时间戳“1649635834”的形式存在的,如下图所示。上图中也标出了时间戳的位置。
    在这里插入图片描述
  • 时间戳也是日期的一种表现形式。在开发者工具中看到的常规格式日期“2022-4-11”实际上是由JavaScript脚本用时间戳“1649635834”渲染出来的。而Requests库获取网页源代码时无法进行实时渲染,所以获取结果不包含常规式日期。现在需要做的就是先提取时间戳,再把它转换为常规格式日期。
  • 包含日期时间戳的网页源代码规律如下:
    timeConvert(‘时间戳’)
  • 正则表达式的编写方式也很简单:
p_date = 'timeConvert('(.*?)')'
  • 但是这行代码在运行时会报错,原因有两个方面:首先,单引号在Python中有特殊含义,这里有嵌套的两对单引号,外层单引号用于定义字符串,内层单引号需要作为普通文本对待。而现在这样的写法会让Python无法区分内外层的单引号,导致正则表达式在第2个引号出中断,Python就无法理解后面内容的意义,就会报错。其次,括号在正则表达式中有特殊意义,这里有嵌套的两对引号,其中外层括号作为特殊文本对待,
  • 所以需要用“\”号来取消符号的特殊含义。即在需要作为普通文本的单引号和括号前都加上“\”号,一共加4个“\”号,代码如下:
p_date = 'timeConvert\(\'(.*?)\'\)'
  • 类似情况并不多见,读者可以做简单了解即可,以后在实践中遇到类似问题,可以模仿上述方法来解决。
  • 用正则表达式提取数据的完整代码如下:
p_title = 'uigs="article_title_.*?">(.*?)</a>' #标题
p_source = 'uigs="article_account_.*?">(.*?)</a>' #来源
p_date = 'timeConvert\(\'(.*?)\'\)' #日期
p_href = '<div class="txt-box">.*?<h3>.*?<a target="_blank" href="(.*?)"' #网址
title = re.findall(p_title,res)
source = re.findall(p_source,res)
date = re.findall(p_date,res)
href = re.findall(p_href,res,re.S) #因为有换行,所以要加上re.S
  • 提取出的标题还夹杂着许多无用的内容,日期还是时间戳的形式,网址也不完整,将在数据清洗环节处理。

3. 数据清洗和打印输出

title[i] = re.sub('<.*?>','',title[i])
title[i] = re.sub('&.*?;','',title[i]) #清洗标题中的“&.*?;格式的内容
  • 如果还有其他格式的无用内容,同样可以用sub()函数进行清理。
  • 将时间戳转换成常规格式的日期,代码如下:
import time
timestamp = int(date[i])
timeArray = time.localtime(timestamp)
date[i] = time.strftime('%Y-%m-%d',timeArray)
  • 第1行代码导入time库,用于将时间戳转换为常规格式的日期。用正则表达式提取的时间戳是字符串,所以在第2行代码用int()函数将其转换为数字。第3行代码将时间戳转换为常规日期。第4行代码指定日期格式为“年-月-日”,其中“月”和“日”为两位数格式。
  • 为网址拼接网站的域名“https://weixin.sogou.com”,代码如下:
href[i] = 'https://weixin.sogou.com' + href[i]
  • 数据清洗和打印输出的完整代码如下:
for i in range(len(title)):
    title[i] = re.sub('<.*?>','',title[i])
    timestamp = int(date[i])
    timeArray = time.localtime(timestamp)
    date[i] = time.strftime('%Y-%m-%d',timeArray)
    href[i] = 'https://weixin.sogou.com' + href[i]
    print(href[i])

完整代码如下:

import requests
import re
import time


headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'}
# 1.获取网页源代码
url = 'https://weixin.sogou.com/weixin?type=2&query=阿里巴巴'
res = requests.get(url,headers=headers,timeout=10).text

# 2.编写正则表达式
p_title = 'uigs="article_title_.*?">(.*?)</a>' #标题
p_source = 'uigs="article_account_.*?">(.*?)</a>' #来源
p_date = 'timeConvert\(\'(.*?)\'\)' #日期
p_href = '<div class="txt-box">.*?<h3>.*?<a target="_blank" href="(.*?)"' #网址
title = re.findall(p_title,res)
source = re.findall(p_source,res)
date = re.findall(p_date,res)
href = re.findall(p_href,res,re.S) #因为有换行,所以要加上re.S

# 3.数据清洗和打印输出
for i in range(len(title)):
    title[i] = re.sub('<.*?>','',title[i])
    timestamp = int(date[i])
    timeArray = time.localtime(timestamp)
    date[i] = time.strftime('%Y-%m-%d',timeArray)
    href[i] = 'https://weixin.sogou.com' + href[i]
    print(str(i + 1) + '.' + title[i] + '+' + source[i] + '+'+ date[i])
    print(href[i])
1.2022年将新增70家哈国企业入驻阿里巴巴+哈萨克斯坦驻华大使馆+2022-04-06
https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSzPlLUV4KbUAepVZjqirVMLwnnGnyLrR21qXa8Fplpd9qecezwipV0tqrvuu-3Nvtc0vQKclBexP3fZLo8BOOqXGM3bDQBGD-P_EW1JRDyK5IMCsOcJg0eFxA6HkVnJtL_l_PCNb9XtdfeLO28DI18a51S-1sJwYSEKjYD2vhqk9pUo2KaGCs69BaT6PXsdoWB_YpQFGaOpp4qUOImqs_CSTJmCU1UgHwQ..&amp;type=2&amp;query=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4&amp;token=B633E972D00FE6828C8E568BC91C00DE8C7AB896625E9E46
2.阿里巴巴云原生混部系统 Koordinator 正式开源+阿里巴巴云原生+2022-04-06
https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSzPlLUV4KbUAepVZjqirVMLwnnGnyLrR21qXa8Fplpd9cYcQBi0mdzMVsDfvXxLUm4xfZKvi4A5TcRpKYm91nOkiZd_TEgowLhx-pMtNsubvsAPq99I4u5wACEp_d2-Mdm9u7ZuXxmOFW4rYD8H_RoYaatGQEBk3LbGkwQUA1dv981lECgHw-prALvMQ6AqPW7bs--WFUAD8ulKyrJniL4-rCDCayYmfpA..&amp;type=2&amp;query=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4&amp;token=B633E972D00FE6828C8E568BC91C00DE8C7AB896625E9E46
3.阿里巴巴精细化运营+课源大圣+2022-04-19
https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSzPlLUV4KbUAepVZjqirVMLwnnGnyLrR21qXa8Fplpd92Jc5E4PlSkIff6uPtbV4cKN7X2yY5fpfEFuQHpA14KrhNY5wkqF1EBqYKBXZWEvfyPMyEjcv3iuWisvvv0bBOFYvpBmsDSqTP8RTg77Fh1ikSsRZ9rVgPrI024jFmmJHy3DiyCVSQyMWvCJa1HegQzw3d_U2XkATKI8DUAJcdNECYioxHkzTmA..&amp;type=2&amp;query=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4&amp;token=B633E972D00FE6828C8E568BC91C00DE8C7AB896625E9E46
4.起底阿里巴巴的商业帝国+大厂好工作+2022-04-19
https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSzPlLUV4KbUAepVZjqirVMLwnnGnyLrR21qXa8Fplpd9-8gA0kxqGNXCvoRqA8-vIZ7JBIcmMIe5NbJ8imsgcZLAfJFV-03XVLscDhBz7yUVorFMlBp6AqaqBVfbtWW18KszonPvNmSE5uxq9P03k9ad9Cd8XOBOUnZjUGlcsygoOj0YuqBcJ42OGs6IUxU_ajI5C6HgvosAnqzjFaBj6bD0OK9DLfgmPA..&amp;type=2&amp;query=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4&amp;token=B633E972D00FE6828C8E568BC91C00DE8C7AB896625E9E46
5.阿里巴巴精细化运营+课源小雪+2022-04-19
https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSzPlLUV4KbUAepVZjqirVMLwnnGnyLrR21qXa8Fplpd9eGMbAnUSscDEsD3Uxlc7IJNPoMbgVU_RwCdisveCs-XlpsB1AqMcD7zSoJewb_NXvVeg1MOAOMWPsjvlUgFAiDIAcyyMuWt7kqZ1xO1XZ_NyFFRTim3BZ1CjZoYhEMaqJM34p-5WCenDzjyDqGj9lSz_GXmN2sSEvlpVQ0HyJTCAFV_3u-a3OQ..&amp;type=2&amp;query=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4&amp;token=B633E972D00FE6828C8E568BC91C00DE8C7AB896625E9E46
6.阿里巴巴精细化运营+小雪爱学习2+2022-04-19
https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSzPlLUV4KbUAepVZjqirVMLwnnGnyLrR21qXa8Fplpd98i_1HnkES15SCWiSF5CBF3KHe9FFjQ3p6CEayUocuL7RYxBCfSrwTM1RA3V9hA2jFyRw05UDoQ_8lckij_2JFDVPoTdb_Z7tpSoadFF159IC5IbjW_FCNWta6ApJsOiDnBMHq0Z28XpMfarWF--TAw7uXlVSqwPplg9PteH4VVg6Ebq8fk9diw..&amp;type=2&amp;query=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4&amp;token=B633E972D00FE6828C8E568BC91C00DE8C7AB896625E9E46

4.定义和调用函数

  • 接下来可以定义和调用函数了。只要把网址中的“阿里巴巴”换成其他公司的名称,就可以爬取关于不同公司的公众号文章信息。
  • 定义函数的核心代码如下:
def weixin(company):
    url = 'https://weixin.sogou.com/weixin?type=2&query=' + company
  • 再添加try/excep异常处理语句(如果爬取不到内容,可以删除异处理语句,通过报错信息来分析原因),爬取微信公众号文章的完整代码如下:

爬取多家公司的微信公众号文章

import requests
import re
import time


headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'}
def weixin(company):
    # 1.获取网页源代码
    url = 'https://weixin.sogou.com/weixin?type=2&query=' + company
    res = requests.get(url,headers=headers,timeout=10).text

    # 2.编写正则表达式
    p_title = 'uigs="article_title_.*?">(.*?)</a>' #标题
    p_source = 'uigs="article_account_.*?">(.*?)</a>' #来源
    p_date = 'timeConvert\(\'(.*?)\'\)' #日期
    p_href = '<div class="txt-box">.*?<h3>.*?<a target="_blank" href="(.*?)"' #网址
    title = re.findall(p_title,res)
    source = re.findall(p_source,res)
    date = re.findall(p_date,res)
    href = re.findall(p_href,res,re.S) #因为有换行,所以要加上re.S

    # 3.数据清洗和打印输出
    for i in range(len(title)):
        title[i] = re.sub('<.*?>','',title[i])
        timestamp = int(date[i])
        timeArray = time.localtime(timestamp)
        date[i] = time.strftime('%Y-%m-%d',timeArray)
        href[i] = 'https://weixin.sogou.com' + href[i]
        print(str(i + 1) + '.' + title[i] + '+' + source[i] + '+'+ date[i])
        print(href[i])

# 4.批量调用函数
compaies = ['华能信托','阿里巴巴','万科集团']
for i in compaies:
    try:
        weixin(i)
        print(i + ':该公司微信公众号文章爬取成功')
        time.sleep(3) # 每爬完一个网页休息3秒,降低触发IP反爬的概率
    except:
        print(i + ':该微信公众号文章爬取失败')
  • 至此就完成了用常规手段爬取微信公众号文章的代码编写,下一节在此基础上添加IP代理,让爬虫任务不会因为爬取过于频繁而中断。

8.2.2 添加IP代理进行爬取

  • 当爬取微信公众号文章的操作太过于频繁时,如进行24小时不间断爬取,那么即使设置每3小时爬取一次,如果爬取的公司很多,依然容易导致IP地址被冻结,此时可以借助IP代理来保障爬虫任务的顺利进行。
  • 最简单的方法就是批量调用weixin()函数的代码前添加下面几行代码:
proxy = requests.get('讯代理API链接').text
proxy = proxy.strip() #这一步很重要,因为要清除换行符等多余的字符
proxies = {"http": "http://"+proxy, "https": "https://"+proxy}
  • 添加后的代码如下:
proxy = requests.get('讯代理API链接').text
proxy = proxy.strip() #这一步很重要,因为要清除换行符等多余的字符
proxies = {"http": "http://"+proxy, "https": "https://"+proxy}
compaies = ['华能信托','阿里巴巴','万科集团']
for i in compaies:
    try:
        weixin(i)
        print(i + ':该公司微信公众号文章爬取成功')
        time.sleep(3) # 每爬完一个网页休息3秒,降低触发IP反爬的概率
    except:
        print(i + ':该微信公众号文章爬取失败')
  • 然后在weixin()函数中访问网址的get()函数中添加proxies=proxies,代码如下:
res = requests.get(url,headers=headers,timeout=10,proxies=proxies).text
  • 这样就可以使用IP代理地址访问搜狗微信网站了。

使用IP爬取多家公司的微信公众号文章(出现了报错)

import requests
import re
import time


headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'}
def weixin(company):
    # 1.获取网页源代码
    url = 'https://weixin.sogou.com/weixin?type=2&query=' + company
    res = requests.get(url,headers=headers,timeout=10,proxies=proxies).text

    # 2.编写正则表达式
    p_title = 'uigs="article_title_.*?">(.*?)</a>' #标题
    p_source = 'uigs="article_account_.*?">(.*?)</a>' #来源
    p_date = 'timeConvert\(\'(.*?)\'\)' #日期
    p_href = '<div class="txt-box">.*?<h3>.*?<a target="_blank" href="(.*?)"' #网址
    title = re.findall(p_title,res)
    source = re.findall(p_source,res)
    date = re.findall(p_date,res)
    href = re.findall(p_href,res,re.S) #因为有换行,所以要加上re.S

    # 3.数据清洗和打印输出
    for i in range(len(title)):
        title[i] = re.sub('<.*?>','',title[i])
        timestamp = int(date[i])
        timeArray = time.localtime(timestamp)
        date[i] = time.strftime('%Y-%m-%d',timeArray)
        href[i] = 'https://weixin.sogou.com' + href[i]
        print(str(i + 1) + '.' + title[i] + '+' + source[i] + '+'+ date[i])
        print(href[i])

# 4.批量调用函数
proxy = requests.get('http://api.xdaili.cn/xdaili-api//greatRecharge/getGreatIp?spiderId=1bfff22283ec488bacc302a679a0a651&orderno=YZ20224181764ow5pXx&returnType=1&count=1').text
proxies = {"http": "http://"+proxy, "https": "https://"+proxy}
compaies = ['华能信托','阿里巴巴','万科集团']
for i in compaies:
    try:
        weixin(i)
        print(i + ':该公司微信公众号文章爬取成功')
        time.sleep(3) # 每爬完一个网页休息3秒,降低触发IP反爬的概率
    except:
        print(i + ':该微信公众号文章爬取失败')
  • 出现如下报错:
requests.exceptions.InvalidURL: Failed to parse: http://121.233.226.245:31173
  • 如果通过IP代理地址不能成功获取到网页源代码,可能的原因是IP代理池里IP代理地址质量参差不齐,有的IP代理地址已经被搜狗列入黑名单。此时可以重新运行代码,提取一个新的IP代理地址(提取频率不要过高,至少间隔5秒),或者利用下一节讲解的只能IP切换系统。

8.2.3 添加智能IP切换系统

  • 上一节使用的IP代理的方式是每运行一次代码就重新获取一次IP代理地址,这样会产生两个问题:第1,一个有效的IP代理地址通常可以使用30分钟以上,过于频繁地重新获取IP代理地址会导致IP资源的浪费;第二,每次运行旨在开头获取IP代理地址,如果获取的是无自动判断IP代理地址是否有效,如果有效就一直使用,如果失效就切换新的有效地址。
  • 在本案例中,当使用的IP代理地址触发了搜狗微信的反爬机制,就认为该地址失效,需要切换。搜狗微信的反爬机制被触发后会显示一个要求用户输入验证码的页面,其网页源代码中含有“请输入途中验证码”的文本。因此,我们可以通过判断获取的网页源代码中是否含有“验证码”三个字来确定是否触发了反爬机制。
  • 具体而言,微信公众号文章爬取的只能IP切换系统搭建主要完成4项工作:
    (1)处理验证码页的乱码;
    (2)将网页源代码设置为weixin()函数的返回值,用于判断是否触发反爬机制;
    (3)编写获取IP代理地址的函数,以方便重复调用;
    (4)合理地构造循环,实现只能IP切换。

1.验证码页乱码的处理

  • 直接使用Requests库获取搜狗微信验证码页的网页源代码,会出现乱码。
  • 因此,需要在获取网页源代码后处理中文乱码。根据5.1.3节的知识,要添加的代码如下:
res = requests.get(url,headers=headers,timeout=10,proxies=proxies).text
try:
    res = res.encode('ISO-8859-1').decode('utf-8')
except:
    try:
        res = res.encode('ISO-8859-1').decode('gbk')
    except:
        res = res
print(res) #如果IP代理地址无效且没有做上面的乱码处理,就能在打印输出的内容中国看到乱码

2.weixin()函数返回值设置

  • 本案例需要依据获取的网页源代码判断是否触发了反爬机制,所以需要在weixin()函数的功能代码最后添加return语句,将获取的网页源代码设置为函数的返回值。具体如下:
def weixin(company):
	......
	# 3. 数据清洗和打印输出
	for i in range(len(title)):
		.......
		print(href[i])
	return res # 将获取的网页源代码设置为函数的返回值
	......
  • weixin()函数的返回值还要用于之后的操作(查看res中是否含有“验证码”三个字),因此,通过如下代码调用函数并获取函数的返回值:
res = weixin(i)

3.编写获取IP代理地址的函数

  • 利用函数返回值的知识,我们可以将获取IP代理地址的代码编写成一个函数,以方便重复调用,代码如下:
def changeip():
    proxy = requests.get('讯代理API链接').text
    proxy = proxy.strip() #这一步很重要,因为要清除换行符等多余的字符
    print('提取IP为: ' + proxy)
    proxies = {"http": "http://"+proxy, "https": "https://"+proxy}
    time.sleep(5)
    return proxies
  • 从讯代理提取IP代理地址的频率上限为每5秒1次,如果提取得太快,会提前失败。
  • 第7行代码设置了返回值,之后就可以通过如下代码来获取IP代理地址了。
proxies = changeip(i)

4.构造循环,实现智能IP切换

  • 利用while else语句构造循环,就能实现智能IP切换,核心代码如下:
res = weixin(i)
while '验证码' in res: #判断网页源代码中是否存在"验证码"三个字
    print('原IP代理地址失效,开始切换IP代理地址')
    proxies = changeip(i)
    res = weixin(i)
else:
    print(i + ':该公司微信公众号文章爬取成功')
  • 智能IP切换系统的完整代码如下:
compaies = ['华能信托','阿里巴巴','万科集团']
for i in compaies:
    try:
        res = weixin(i)
        while '验证码' in res:  # 判断网页源代码中是否存在"验证码"三个字
            print('原IP代理地址失效,开始切换IP代理地址')
            proxies = changeip()
            res = weixin(i)
        else:
            print(i + ':该公司微信公众号文章爬取成功')
    except:
        print(i + ':该公司微信公众号文章爬取成功')
  • 第1行代码调用changip()函数获取一个IP代理地址并赋给变量proxies,这样第6行代码调用微信()函数时才不会报错,因为weixin()函数中访问网址时为get()函数设置了proxies参数。
  • 讯代理提供的IP代理地址是公共IP地址,失效的可能性较大,使用上述只能IP切换系统则能较好地保证爬虫代码的正常运行。不过笔者还是建议使用自己的IP地址为主,并控制好访问频率,例如,每爬完一页后用time.sleep(3)休息3秒。
  • 整个项目的完整代码如下;
import requests
import re
import time
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'}

def weixin(company):
    # 1.获取网页源代码
    url = 'https://weixin.sogou.com/weixin?type=2&query=' + company
    #url = 'http://httpbin.org/get' #用于查看IP地址是否应用成功
    res = requests.get(url,headers=headers,timeout=10,proxies=proxies).text
    try:
        res = res.encode('ISO-8859-1').decode('utf-8')
    except:
        try:
            res = res.encode('ISO-8859-1').decode('gbk')
        except:
            res = res
    #print(res)  # 如果IP代理地址无效且没有做上面的乱码处理,就能在打印输出的内容中国看到乱码

    # 2.编写正则表达式
    p_title = 'uigs="article_title_.*?">(.*?)</a>' #标题
    p_source = 'uigs="article_account_.*?">(.*?)</a>' #来源
    p_date = 'timeConvert\(\'(.*?)\'\)' #日期
    p_href = '<div class="txt-box">.*?<h3>.*?<a target="_blank" href="(.*?)"' #网址
    title = re.findall(p_title,res)
    source = re.findall(p_source,res)
    date = re.findall(p_date,res)
    href = re.findall(p_href,res,re.S) #因为有换行,所以要加上re.S

    # 3.数据清洗和打印输出
    for i in range(len(title)):
        title[i] = re.sub('<.*?>','',title[i])
        timestamp = int(date[i])
        timeArray = time.localtime(timestamp)
        date[i] = time.strftime('%Y-%m-%d',timeArray)
        href[i] = 'https://weixin.sogou.com' + href[i]
        print(str(i + 1) + '.' + title[i] + '+' + source[i] + '+'+ date[i])
        print(href[i])
    return res # 将获取的网页源代码设置为函数的返回值



def changeip():
    proxy = requests.get('http://api.xdaili.cn/xdaili-api//greatRecharge/getGreatIp?spiderId=1bfff22283ec488bacc302a679a0a651&orderno=YZ20224181764ow5pXx&returnType=1&count=10').text
    proxy = proxy.strip()
    print('提取IP为: ' + proxy)
    proxies = {"http": "http://"+proxy, "https": "https://"+proxy}
    time.sleep(5)
    return proxies

proxies = changeip()

# 下面进行智能IP切换
compaies = ['华能信托','阿里巴巴','万科集团']
for i in compaies:
    try:
        res = weixin(i)
        while '验证码' in res:  # 判断网页源代码中是否存在"验证码"三个字
            print('原IP代理地址失效,开始切换IP代理地址')
            proxies = changeip()
            res = weixin(i)
        else:
            print(i + ':该公司微信公众号文章爬取成功')
    except:
        print(i + ':该公司微信公众号文章爬取失败')
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值