python爬取Ajax动态加载网页过程解析

论坛 期权论坛 脚本     
niminba   2021-5-23 03:28   1529   0

常见的反爬机制及处理方式

1、Headers反爬虫 :Cookie、Referer、User-Agent

解决方案: 通过F12获取headers,传给requests.get()方法

2、IP限制 :网站根据IP地址访问频率进行反爬,短时间内进制IP访问

解决方案:

1、构造自己IP代理池,每次访问随机选择代理,经常更新代理池

2、购买开放代理或私密代理IP

3、降低爬取的速度

3、User-Agent限制 :类似于IP限制

解决方案: 构造自己的User-Agent池,每次访问随机选择

5、对查询参数或Form表单数据认证(salt、sign)

解决方案: 找到JS文件,分析JS处理方法,用Python按同样方式处理

6、对响应内容做处理

解决方案: 打印并查看响应内容,用xpath或正则做处理

python中正则处理headers和formdata

1、pycharm进入方法 :Ctrl + r ,选中 Regex

2、处理headers和formdata

(.*): (.*)

"1":"1":"2",

3、点击 Replace All

民政部网站数据抓取

目标: 抓取最新中华人民共和国县以上行政区划代码

URL: http://www.mca.gov.cn/article/sj/xzqh/2019/ - 民政数据 - 行政区划代码

实现步骤

1、从民政数据网站中提取最新行政区划代码链接

最新的在上面,命名格式: 2019年X月中华人民共和国县以上行政区划代码

import requests
from lxml import etree
import re
​
url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
html = requests.get(url, headers=headers).text
parse_html = etree.HTML(html)
article_list = parse_html.xpath('//a[@class="artitlelist"]')
​
for article in article_list:
  title = article.xpath('./@title')[0]
  # 正则匹配title中包含这个字符串的链接
  if title.endswith('代码'):
    # 获取到第1个就停止即可,第1个永远是最新的链接
    two_link = 'http://www.mca.gov.cn' + article.xpath('./@href')[0]
    print(two_link)
    break

2、从二级页面链接中提取真实链接(反爬-响应网页内容中嵌入JS,指向新的网页链接)

向二级页面链接发请求得到响应内容,并查看嵌入的JS代码

正则提取真实的二级页面链接

# 爬取二级“假”链接
two_html = requests.get(two_link, headers=headers).text
# 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
new_two_link = re.findall(r'window.location.href="(.*?)" rel="external nofollow" rel="external nofollow" ', two_html, re.S)[0]

3、在数据库表中查询此条链接是否已经爬取,建立增量爬虫

数据库中建立version表,存储爬取的链接

每次执行程序和version表中记录核对,查看是否已经爬取过

cursor.execute('select * from version')
result = self.cursor.fetchall()
if result:
  if result[-1][0] == two_link:
    print('已是最新')
  else:
    # 有更新,开始抓取
    # 将链接再重新插入version表记录

4、代码实现

import requests
from lxml import etree
import re
import pymysql
class GovementSpider(object):
  def __init__(self):
    self.url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
    self.headers = {'User-Agent': 'Mozilla/5.0'}
    # 创建2个对象
    self.db = pymysql.connect('127.0.0.1', 'root', '123456', 'govdb', charset='utf8')
    self.cursor = self.db.cursor()
  # 获取假链接
  def get_false_link(self):
    html = requests.get(url=self.url, headers=self.headers).text
    # 此处隐藏了真实的二级页面的url链接,真实的在假的响应网页中,通过js脚本生成,
    # 假的链接在网页中可以访问,但是爬取到的内容却不是我们想要的
    parse_html = etree.HTML(html)
    a_list = parse_html.xpath('//a[@class="artitlelist"]')
    for a in a_list:
      # get()方法:获取某个属性的值
      title = a.get('title')
      if title.endswith('代码'):
        # 获取到第1个就停止即可,第1个永远是最新的链接
        false_link = 'http://www.mca.gov.cn' + a.get('href')
        print("二级“假”链接的网址为", false_link)
        break
    # 提取真链接
    self.incr_spider(false_link)
  # 增量爬取函数
  def incr_spider(self, false_link):
    self.cursor.execute('select url from version where url=%s', [false_link])
    # fetchall: (('http://xxxx.html',),)
    result = self.cursor.fetchall()

    # not result:代表数据库version表中无数据
    if not result:
      self.get_true_link(false_link)
      # 可选操作: 数据库version表中只保留最新1条数据
      self.cursor.execute("delete from version")

      # 把爬取后的url插入到version表中
      self.cursor.execute('M%%%M4(vrv%r>`rv>.4(輽йэ	%%4(Z4(鉅4)}(5饱]9P]=\]-м-!Q50
M4(5饱]9P]=\4(5饱иM%9P]=\миM1
9P
1H9P
1H9P
1H5
A9PиA4)t4(4)4)4)4))}4)QФ}}|}輽йэE%%%%%M4(}輽йэ	%%4(й&O(}cR>[j_64(:>[N74(UМ}С(_V6z,4(4(胢:>[&r'V64(}}}4(4(lфulAtltlI9tB7(}lA%t%.vrv4(.rv:>[3J34(}}С}4(llt}}}4(С4(}*""_(zCv4(}}}}4(lфulIt(qq:'604(lфulIНt4(qq:'604(4(:>[V(}Р4(4(Сlфul
Нt?r$:6@4(4(4(}}С4(}}4("rrZ(}}4(4)}}}|}}}|4(4(4(4(Р&3^^4(brZj3ro疒j惚r'&*rokkR2
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP