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错误和解决方法汇总整理
Jun 03 Python
Python编程中的异常处理教程
Aug 21 Python
使用Python实现windows下的抓包与解析
Jan 15 Python
tensorflow1.0学习之模型的保存与恢复(Saver)
Apr 23 Python
Python使用matplotlib实现的图像读取、切割裁剪功能示例
Apr 28 Python
在python中pandas读文件,有中文字符的方法
Dec 12 Python
python制作mysql数据迁移脚本
Jan 01 Python
python getopt模块使用实例解析
Dec 18 Python
Python中如何将一个类方法变为多个方法
Dec 30 Python
pytorch 实现多个Dataloader同时训练
May 29 Python
Python中22个万用公式的小结
Jul 21 Python
利用Python读取微信朋友圈的多种方法总结
Aug 23 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遍历数组的方法分享
2012/03/22 PHP
利用js跨页面保存变量做菜单的方法
2008/01/17 Javascript
JavaScript高级程序设计 XML、Ajax 学习笔记
2011/09/10 Javascript
jquery ui对话框实例代码
2013/05/10 Javascript
nodejs简单实现中英文翻译
2015/05/04 NodeJs
jQuery实现的网格线绘制方法
2016/06/20 Javascript
Vue.js第一天学习笔记(数据的双向绑定、常用指令)
2016/12/01 Javascript
Angular.js实现注册系统的实例详解
2016/12/18 Javascript
详解使用nodeJs安装Vue-cli
2017/05/17 NodeJs
js实现省市级联效果分享
2017/08/10 Javascript
解决vue 打包发布去#和页面空白的问题
2018/09/04 Javascript
vue-devtools的安装和使用步骤详解
2019/10/17 Javascript
vue 中url 链接左边的小图标更改问题
2019/12/30 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
VUE项目axios请求头更改Content-Type操作
2020/07/24 Javascript
JS面向对象实现飞机大战
2020/08/26 Javascript
vue-cli —— 如何局部修改Element样式
2020/10/22 Javascript
[02:38]DOTA2英雄基础教程 噬魂鬼
2014/01/03 DOTA
从Python的源码浅要剖析Python的内存管理
2015/04/16 Python
Python实现处理管道的方法
2015/06/04 Python
Python利用字典将两个通讯录文本合并为一个文本实例
2018/01/16 Python
面向初学者的Python编辑器Mu
2018/10/08 Python
Win10系统下安装labelme及json文件批量转化方法
2019/07/30 Python
什么是python的自省
2020/06/21 Python
荷兰本土平价百货:HEMA
2017/10/23 全球购物
UGG美国官网:购买UGG雪地靴、拖鞋和鞋子
2017/12/31 全球购物
SKECHERS斯凯奇中国官网:来自美国的运动休闲品牌
2018/11/14 全球购物
25道Java面试题集合
2013/05/21 面试题
计算机应用专业推荐信
2013/11/13 职场文书
班组长工作职责
2013/12/25 职场文书
编辑找工作求职信分享
2014/01/03 职场文书
专业求职信撰写要诀
2014/02/18 职场文书
企业文化口号
2014/06/12 职场文书
2014年派出所工作总结
2014/11/21 职场文书
Python爬虫之爬取二手房信息
2021/04/27 Python
opencv深入浅出了解机器学习和深度学习
2022/03/17 Python