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使用socket远程连接错误处理方法
Apr 29 Python
Python3 操作符重载方法示例
Nov 23 Python
Python实现七彩蟒蛇绘制实例代码
Jan 16 Python
python分治法求二维数组局部峰值方法
Apr 03 Python
Python解析并读取PDF文件内容的方法
May 08 Python
基于scrapy的redis安装和配置方法
Jun 13 Python
Python设计模式之状态模式原理与用法详解
Jan 15 Python
详解用python计算阶乘的几种方法
Aug 14 Python
Python 元组操作总结
Sep 18 Python
python打印直角三角形与等腰三角形实例代码
Oct 20 Python
Django ModelForm操作及验证方式
Mar 30 Python
Python request使用方法及问题总结
Apr 26 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字符串截取问题
2006/11/28 PHP
php 正确解码javascript中通过escape编码后的字符
2010/01/28 PHP
php用正则表达式匹配中文实例详解
2013/11/06 PHP
php中time()与$_SERVER[REQUEST_TIME]用法区别
2014/11/19 PHP
Laravel 5.0 发布 新版本特性详解
2015/02/10 PHP
javascript数组使用调用方法汇总
2007/12/08 Javascript
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
根据选择不同的下拉值出现相对应的文本输入框
2013/08/01 Javascript
在子窗口中关闭父窗口的一句代码
2013/10/21 Javascript
Javascript实现飞动广告效果的方法
2015/05/25 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
基于jquery编写分页插件
2016/03/07 Javascript
JQuery省市联动效果实现过程详解
2020/05/08 jQuery
在python带权重的列表中随机取值的方法
2019/01/23 Python
python 字符串常用函数详解
2019/09/11 Python
opencv python在视屏上截图功能的实现
2020/03/05 Python
python Xpath语法的使用
2020/11/26 Python
微信浏览器左上角返回按钮拦截功能
2017/11/21 HTML / CSS
只要五步 就可以用HTML5/CSS3快速制作便签贴特效(图)
2012/06/04 HTML / CSS
深入剖析HTML5 内联框架iFrame
2016/05/04 HTML / CSS
英国品牌男装折扣网站:Brown Bag
2018/03/08 全球购物
Speedo速比涛德国官方网站:世界领先的泳装品牌
2019/08/26 全球购物
Carrs Silver官网:英国著名的银器品牌
2020/08/29 全球购物
在SQL Server中创建数据库主要有那种方式
2013/09/10 面试题
最新远光软件笔试题面试题内容
2013/11/08 面试题
应届大学生求职的自我评价
2013/11/17 职场文书
寒假实习自荐信
2014/01/26 职场文书
高中地理教学反思
2014/01/29 职场文书
火车的故事教学反思
2014/02/11 职场文书
工业自动化专业自荐信范文
2014/04/10 职场文书
幼儿教师暑期培训方案
2014/08/27 职场文书
客户经理岗位职责大全
2015/04/09 职场文书
爱护环境卫生倡议书
2015/04/29 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书
go语言使用Casbin实现角色的权限控制
2021/06/26 Golang
Zabbix6通过ODBC方式监控Oracle 19C的详细过程
2022/09/23 Servers