python爬取微信公众号文章


Posted in Python onAugust 31, 2018

本文实例为大家分享了python爬取微信公众号文章的具体代码,供大家参考,具体内容如下

# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
from requests.exceptions import RequestException
import time
import random
import MySQLdb
import threading
import socket
import math
 
socket.setdefaulttimeout(60)#这里对整个socket层设置超时时间。后续文件中如果再使用到socket,不必再设置
 
glock = threading.Lock() #定义全局锁
 
CATEGORY_URL= ['http://www.we123.com/gzh/onclick/'] #获取地区分类链接
all_url = [] #
ALL_URLS = [] #所有详细页面链接
proxy_list = [] #IP池
URL = 'http://www.we123.com'
PAGE_URL = [] #所有分页链接
 
#获取Ip池
def get_ip():
  headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
  url = 'http://http-webapi.zhimaruanjian.com'#可以使用芝麻代理,好用稳定还不贵
  resp = requests.get(url,headers=headers)
  obj = resp.json() #获取json ip池对象
  for ip in obj:
    arr = 'http://' + str(ip['ip']) + ':' + str(ip['port'])
    proxy_list.append(arr)
 
#获取页面源码函数
def get_html(url):
  # headers = {}
  user_agent_list = [
    'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3538.400 QQBrowser/9.6.12501.400',
    'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0'
  ]
  # user_agent = random.choice(user_agent_list)
  headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3538.400 QQBrowser/9.6.12501.400'
  }
  # 代理,免费的代理只能维持一会可能就没用了,自行更换
  # proxy_list = [
  #   "http://27.192.185.62:3252",
  # ]
  # proxy_ip = random.choice(proxy_list)
  # proxies = {'http': proxy_ip}
  # print(str(url))
  try:
    resp = requests.get(url,headers=headers)
    # print("72行:status_code = " + str(resp.status_code))
    # print(type(resp.text))
    # print(resp.url) # 请求的url
    if resp.status_code == 200:
      return resp
    elif resp.status_code == 404:
      return resp
    elif resp.status_code == 500:
      return resp
    return resp
  except RuntimeError:
    print("超时")
    return "error"
  except ConnectionError:
    print("连接超时")
    return "error"
  except RequestException:
    print("http请求父类错误")
    with open('url_exception.txt','a+', encoding='utf-8') as f:
      f.write(str(url))
      f.write('\n')
    return "error"
 
#获取区域分类链接
def get_categoty_url():
  url = 'http://www.we123.com/gzh/onclick/'
  resp = get_html(url)
  soup = BeautifulSoup(resp.text,'lxml')
  html = soup.select('div.div-subs2 > div.divst-content > div.divst-subs > li > a')
  # 获取区域分类链接
  for i in html:
    city = i['href'].split("/")[-1]
    if (city == '海外' or city == '台湾' or city == '澳门'):
      continue
    url = URL + i['href']
    CATEGORY_URL.append(url)
  print(CATEGORY_URL)
 
 
#获取每个区域下所有分页链接
def get_page_url(url):
  city = url.split('/')[-1]
  html = get_html(url)
  if html == "error":
    print("98行:connect url error")
    time.sleep(random.randint(10,20))
    return "error"
  soup = BeautifulSoup(html.text,'lxml')
  #获取总条数
  all_nums = soup.select("div.page > a > b")
  if len(all_nums) == 0:
    return "error"
  else:
    all_nums = soup.select("div.page > a > b")[0].get_text()
  #获取总分页数
  all_pages = math.ceil((int(all_nums) / 30))
  #获取所有分页链接
  all_page_url = []
  for i in range(0,int(all_pages)):
    page_url = 'http://www.we123.com/e/action/ListInfo.php?page=' + str(i) + '&classid=45&line=30&tempid=10&orderby=onclick&myorder=0&totalnum=' + str(all_nums)
    all_page_url.append(page_url)
  return all_page_url
 
# 获取所有详细页面链接
def get_page_urls():
    global PAGE_URL
    c_url = CATEGORY_URL.pop()
    print('121 行:请求链接' + c_url)
    PAGE_URL = get_page_url(c_url) #获取每个区域下面的所有分页链接
 
# 获取所有详细页面链接
def get_info_urls():
  while True:
    global PAGE_URL #设置全局变量
    glock.acquire() #加锁
    if len(PAGE_URL) == 0:
      glock.release() #解锁
      print('131 行:CATEGORY_URL 为空')
      break
    else:
      p_url = PAGE_URL.pop()
      print('135 行:请求链接' + p_url)
      glock.release() #解锁
 
      glock.acquire() #加锁
      html = get_html(p_url)
      if html == "error":
        print("141行:connect url error")
        time.sleep(2)
        return
      soup = BeautifulSoup(html.text,'lxml')
      info_urls = soup.select('div.gzhRight > div.gzh_list > ul > li > a')
      for x in info_urls:
        i_url = URL + x['href']
        ALL_URLS.append(i_url)
      print("库存链接共:" + str(len(ALL_URLS)))
    glock.release() #解锁
#获取每一页需要的数据
def get_data():
  while True:
    global ALL_URLS #设置全局变量
    glock.acquire() #加锁
    print("当前库存:"+str(len(ALL_URLS)))
    if len(ALL_URLS) == 0:
      glock.release() #解锁
      print('159 行 :ALL_URLS 为空')
      break
    else:
      url = ALL_URLS.pop()
      print("开始抓取数据:" + url)
      glock.release() #解锁
      time.sleep(1) #睡眠1秒钟
      html = get_html(url)
      if html == "error":
        print("168行:connect url error")
        time.sleep(random.randint(2, 4))
        return
      html.encoding='utf-8' #显式地指定网页编码,一般情况可以不用
      soup = BeautifulSoup(html.text,'lxml')
      #公众号名称
      names = soup.select('div.artcleLeft > div.xcxnry > div.xcxtop > div.xcxtop_left > div.gzhtop_logo > h1')
      #微信号id
      accounts = []
      accounts.append(soup.select('div.artcleLeft > div.xcxnry > div.xcxtop > div.xcxtop_left > div.gzhtop_logo > p')[0])
      #微信头像
      imgs = soup.select('div.artcleLeft > div.xcxnry > div.xcxtop > div.xcxtop_left > div.gzhtop_logo > img')
      #公众号二维码
      QR_codes= soup.select('div.artcleLeft > div.xcxnry > div.xcxtop > div.xcxtop_right > img')
      #介绍
      descs = soup.select('div.artcleLeft > div.xcxnry > div.xcxinfo')
      #公众号分类
      categorys = []
      category = ''
      cate = soup.select('div.artcleLeft > div.xcxnry > div.xcxtop > div.xcxtop_left > div.xcx_p > span > a')
      if not len(cate) == 0:
        category = cate[0].get_text()
      else:
        category = '综合'
      glock.acquire() #加锁
      for name,account,img,QR_code,desc in zip(names,accounts,imgs,QR_codes,descs):
        data = {
          'name':name.get_text(),
          'category':category,
          'account':account.get_text().split(":")[-1],
          'img':img['src'],
          'QR_code':QR_code['src'],
          'desc':desc.get_text()
        }
        add_data(data,url)
      glock.release() #解锁
#添加数据
def add_data(data,url):
  con = MySQLdb.connect('127.0.0.1','root','root','test',charset="utf8",use_unicode=True)
  cursor = con.cursor()
  # exit()
  insert_sql = """
    insert ignore into weixin5(w_name,category,account,img,QR_code,introduce)
    VALUES (%s,%s,%s,%s,%s,%s)
    """
  print('212行 :' + data['name'] + '_' + data['account'] + '添加成功!-' + url)
  try:
    cursor.execute(insert_sql,(data['name'],data['category'],data['account'],data['img'],data['QR_code'],str(data['desc'])))
    con.commit()
  except:
    ALL_URLS.insert(0,url)
    print("218行:" + URL + '插入失败')
    con.rollback()
  con.close()
 
# 将时间字符串转化为时间戳
def time_to(dt):
  timeArray = time.strptime(dt, "%Y年%m月%d日")
  timestamp = int(time.mktime(timeArray))
  return timestamp
 
#启动多线程爬取
def main():
  for x in range(3):
    th = threading.Thread(target=get_info_urls)
    th.start()
     # get_info_urls()
  time.sleep(3)
  for x in range(5):
    th = threading.Thread(target=get_data)
    th.start()
 
if __name__ == '__main__':
  # 计时
  t1 = time.time()
  # 调用函数
  get_ip() #获取ip池
  get_page_urls()
  time.sleep(2)
  # get_categoty_url()
  main()
  print(time.time() - t1)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中使用动态变量名的方法
May 06 Python
Django forms组件的使用教程
Oct 08 Python
对Python中list的倒序索引和切片实例讲解
Nov 15 Python
Python使用字典的嵌套功能详解
Feb 27 Python
python仿evething的文件搜索器实例代码
May 13 Python
使用apiDoc实现python接口文档编写
Nov 19 Python
django 实现celery动态设置周期任务执行时间
Nov 19 Python
PyCharm使用之配置SSH Interpreter的方法步骤
Dec 26 Python
关于tf.reverse_sequence()简述
Jan 20 Python
python实现ssh及sftp功能(实例代码)
Mar 16 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
Mar 30 Python
Restful_framework视图组件代码实例解析
Nov 17 Python
Python单向链表和双向链表原理与用法实例详解
Aug 31 #Python
Python使用Flask-SQLAlchemy连接数据库操作示例
Aug 31 #Python
浅谈Python traceback的优雅处理
Aug 31 #Python
python梯度下降法的简单示例
Aug 31 #Python
wxPython的安装与使用教程
Aug 31 #Python
python traceback捕获并打印异常的方法
Aug 31 #Python
基于python中theano库的线性回归
Aug 31 #Python
You might like
PHP基于rabbitmq操作类的生产者和消费者功能示例
2018/06/16 PHP
浅析PHP 中move_uploaded_file 上传中文文件名失败
2019/04/17 PHP
JS连连看源码完美注释版(推荐)
2013/12/09 Javascript
深入理解javascript中的立即执行函数(function(){…})()
2014/06/12 Javascript
jquery操作 iframe的方法
2014/12/03 Javascript
小米公司JavaScript面试题
2014/12/29 Javascript
JavaScript toUpperCase()方法使用详解
2016/08/26 Javascript
jQuery中ScrollTo用法示例
2016/09/04 Javascript
阿里云ecs服务器中安装部署node.js的步骤
2016/10/08 Javascript
JS和canvas实现俄罗斯方块
2017/03/14 Javascript
浅谈React Event实现原理
2018/09/20 Javascript
对 Vue-Router 进行单元测试的方法
2018/11/05 Javascript
微信小程序模板template简单用法示例
2018/12/04 Javascript
VUE 实现复制内容到剪贴板的两种方法
2019/04/24 Javascript
node.js express捕获全局异常的三种方法实例分析
2019/12/27 Javascript
基于vue--key值的特殊用处详解
2020/07/31 Javascript
OpenLayers3实现对地图的基本操作
2020/09/28 Javascript
详解实现vue的数据响应式原理
2021/01/20 Vue.js
python去除所有html标签的方法
2015/05/05 Python
Python循环语句之break与continue的用法
2015/10/14 Python
Python md5与sha1加密算法用法分析
2017/07/14 Python
在Python中使用defaultdict初始化字典以及应用方法
2018/10/31 Python
python创建与遍历List二维列表的方法
2019/08/16 Python
关于sys.stdout和print的区别详解
2019/12/05 Python
python输出pdf文档的实例
2020/02/13 Python
python编写俄罗斯方块
2020/03/13 Python
用CSS3和table标签实现一个圆形轨迹的动画的示例代码
2019/01/17 HTML / CSS
总结html5自定义属性有哪些
2020/04/01 HTML / CSS
Oakley西班牙官方商店:太阳眼镜和男女运动服
2019/04/26 全球购物
LUISAVIAROMA中国官网:时尚奢侈品牌购物网站
2020/11/01 全球购物
size?荷兰官方网站:英国高级运动鞋精品店
2020/07/24 全球购物
中专毕业生的自我鉴定
2013/12/01 职场文书
大学班级学风建设方案
2014/05/01 职场文书
员工生日活动方案
2014/08/24 职场文书
成品仓管员岗位职责
2015/04/01 职场文书
2016庆祝国庆67周年宣传语
2015/11/25 职场文书