requests+xpath爬虫实战--csv存储

2019-3 九龙坡爬虫

目标:爬取url='http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002’里面70页所有的1.中标公示的名称 日期,以及每个中标公告的url
2.进入每个url爬取里面的字段
在这里插入图片描述
这是每个中标公示里面的内容:我们需要爬取项目名称,招标公告编号,招标人,招标代理机构,招标结果中的三个待定中标者,中标人,以及投诉受理部门。
在这里插入图片描述
爬虫步骤:
1.获取每个html界面,并解析每个html界面
2.用xpath定位器取东西
3.将爬取的数据进行存储

爬虫中需要解决的问题:
1.如何获取每个界面,(网页翻页问题)
2.如何正确的取到需要的数据的xpath,(有坑)
3.csv数据格式 存储问题

解决问题:
1.当点击下一页的时候,发现上方的url不变,这就很奇怪了,那怎样让程序自动到下一页呢?
在这里插入图片描述
这种:url只有一个,但是可以有很多界面的问题,就需要我们抓包,查看表单数据,通过post请求修改表单数据,从而翻页。

1.先鼠标右击 选 检查,选择上方的network,再选择doc,之后点击一下 下一页,服务器就会发过来下面三个包裹,点击第一个,
在这里插入图片描述
fromdata就是表单数据,往下翻会有出现,_EVEENTEVENTARGUMENT:3, (为什么会看表单数据中的这个? 因为每一个下一页,你去看表单数据,你会发现,当是第三页的时候,这个参数是3,当第四页的时候,会是4,所以不同界面,跟这个参数有关。)
在这里插入图片描述
第四页的时候,这个参数后面数字是4,多看几个,发现第几页,这个数字就是多少,因此我们只需要修改这个表单数据中的这个参数,就能实现翻页了
在这里插入图片描述

在这里插入图片描述

实现翻页的代码:(用循环,实现70页的翻页)

import requests
from lxml import etree
  for i in range(1,71):
        url='http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'
        headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3626.400 QQBrowser/10.4.3211.400',
   		'Referer':'http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'}
    #post请求修改表单数据 只需要写要修改的部分,不需要把表单里的全部内容都写进去
        playload={'__EVENTARGUMENT':i}#post请求修改表单数据实现翻页
        r=requests.post(url, headers=headers, data=playload,timeout=30)
        r.encoding='utf-8'
        html=etree.HTML(r.text)#用etree解析界面,从而可以使用xpath定位器

2.xpath的坑,切记不要经常在浏览器上直接复制xpath,虽然直接复制的能在xpath匹配器上匹配得到东西,但是放在代码里,偶尔会错。(因为浏览器上有时会自动规范网页,会出现多余对的标签,主要会出现tbody标签,)。因此每次从浏览器上复制的xpath 出现tbody 就把它删除用//代替
3.注意:csv写入excel的坑:
1.当header(列表)有的时候,要写入的数据infos中字典的键要与header中的值一样
2.infos一定要为列表 ,并且需要当全部数据都装在infos中后,才开始存进本地。

全代码:

import requests
import csv
from bs4 import BeautifulSoup
from lxml import etree


def main():
    #global url
    #url='http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'
   # headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) #Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3626.400 QQBrowser/10.4.3211.400',
   #'Referer':'http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'}
   
    infos=[]
    header2=['公告','时间','网址','项目名称','招标公告编号','招标人','招标代理机构','待选者1','待选者2','待选者3','中标人','投诉受理部门']
    #post修改表单数据,实现翻页
    for i in range(1,71):
        url='http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'
        headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3626.400 QQBrowser/10.4.3211.400',
   'Referer':'http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'}
    #post请求修改表单数据 只需要写要修改的部分,不需要把表单里的全部内容都写进去
        playload={'__VIEWSTATEGENERATOR': '7A07C098','__EVENTTARGET': 'MoreInfoList1$Pager','__EVENTARGUMENT':i}
        r=requests.post(url, headers=headers, data=playload,timeout=30)
        r.encoding='utf-8'  #或者 r.content.decode('utf-8') html=etree.HTML(r)
        html=etree.HTML(r.text)
#xpath提取所有tr标签 尾部没有text()
        trs = html.xpath("//table[@id]//td[@id='MoreInfoList1_tdcontent']//tr")
        for tr in trs:
            #取表题,[0]表示取值
            name=tr.xpath('.//td[2]/a/text()')[0]
            #取日期
            time=(tr.xpath('./td[3]/text()')[0]).replace('\n','').replace('\r','')
            #拼接url
            url="http://www.cqjlpggzyzhjy.gov.cn" + tr.xpath("./td[2]/a/@href")[0]
            r2=requests.get(url,headers=headers).text
            r.encoding='utf-8'
            html2=etree.HTML(r2)
            #注意tbody,最好删除,切记不可直接复制浏览器中的xpath,有时会出错。
            #每个公告里面需要提取的字段。
            a=html2.xpath("//*[@id='TDContent']/div/table//tr[1]/td[2]/p/text()")
            b=html2.xpath("//*[@id='TDContent']/div/table//tr[2]/td[2]/p/span/text()")
            c=html2.xpath("//*[@id='TDContent']/div/table//tr[3]/td[2]/p//text()")
            d=html2.xpath("//*[@id='TDContent']/div/table//tr[4]/td[2]/p/span/text()")
            e=html2.xpath("//*[@id='TDContent']/div/table//tr[6]/td[2]/p/span/text()")
            f=html2.xpath("//*[@id='TDContent']/div/table//tr[7]/td[2]/p/span/text()")
            g=html2.xpath("//*[@id='TDContent']/div/table//tr[8]/td[2]/p/span/text()")
            h=html2.xpath("//*[@id='TDContent']/div/table//tr[9]/td[2]/p/span/text()")
            i=html2.xpath("//*[@id='TDContent']/div/table//tr[10]/td[2]/p/span/text()")
            data={'公告':name,
                  '时间':time,
                  '网址':url,
                  '项目名称':a,
                  '招标公告编号':b,
                  '招标人':c,
                  '招标代理机构':d,
                  '待选者1':e,
                  '待选者2':f,
                  '待选者3':g,
                  '中标人':h ,
                  '投诉受理部门':i,}
                
            infos.append(data)
        
   #当数据全部存放在infos中后,保存数据
    with open('2019-3 九龙坡.csv','w',encoding='utf-8',newline='') as fp:
        writer=csv.DictWriter(fp,header2)
        writer.writeheader()
        writer.writerows(infos)
main()

文章作者:张川

作者QQ:468336329

备注:本文纯属原创,未经同意请勿转载。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值